diff options
Diffstat (limited to 'tools')
285 files changed, 19228 insertions, 7085 deletions
diff --git a/tools/Makefile b/tools/Makefile index 4fe91f665a1..9a354f6c706 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -10,62 +10,109 @@ curdir:=tools # subdirectories to descend into tools-y := -ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN)$(CONFIG_GCC_LLVM),) -tools-y += gmp mpfr mpc libelf + +ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),) + BUILD_TOOLCHAIN := y + ifdef CONFIG_GCC_USE_GRAPHITE + BUILD_ISL = y + endif +endif +ifneq ($(CONFIG_SDK)$(CONFIG_PACKAGE_kmod-b43)$(CONFIG_PACKAGE_b43legacy-firmware)$(CONFIG_BRCMSMAC_USE_FW_FROM_WL),) + BUILD_B43_TOOLS = y endif -tools-y += m4 libtool autoconf automake flex bison pkg-config sed mklibs -tools-y += sstrip ipkg-utils genext2fs e2fsprogs mtd-utils mkimage -tools-y += firmware-utils patch-cmdline quilt yaffs2 flock padjffs2 -tools-y += mm-macros xorg-macros xfce-macros missing-macros xz cmake + +tools-$(BUILD_TOOLCHAIN) += gmp mpfr mpc libelf expat +tools-y += m4 libtool autoconf automake flex bison pkg-config mklibs zlib +tools-y += sstrip make-ext4fs e2fsprogs mtd-utils mkimage +tools-y += firmware-utils patch-image quilt padjffs2 +tools-y += mm-macros missing-macros cmake scons bc findutils gengetopt patchelf +tools-y += mtools dosfstools libressl tools-$(CONFIG_TARGET_orion_generic) += wrt350nv2-builder upslug2 -tools-$(CONFIG_powerpc) += upx tools-$(CONFIG_TARGET_x86) += qemu -ifneq ($(CONFIG_TARGET_ar71xx),) -tools-y += lzma-old squashfs -endif +tools-$(CONFIG_TARGET_mxs) += elftosb sdimage +tools-$(CONFIG_TARGET_ar71xx) += lzma-old +tools-$(CONFIG_TARGET_ar71xx)$(CONFIG_TARGET_ath79) += squashfs +tools-$(CONFIG_USES_MINOR) += kernel2minor tools-y += lzma squashfs4 +tools-$(BUILD_B43_TOOLS) += b43-tools +tools-$(BUILD_ISL) += isl +tools-$(CONFIG_USE_SPARSE) += sparse +tools-$(CONFIG_TARGET_apm821xx) += genext2fs -ifdef CONFIG_GCC_USE_GRAPHITE - ifeq ($(CONFIG_GCC_USE_SYSTEM_PPL_CLOOG),) - tools-y += ppl cloog - $(curdir)/cloog/compile := $(curdir)/ppl/install - endif +# builddir dependencies +$(curdir)/bison/compile := $(curdir)/flex/compile +$(curdir)/flex/compile := $(curdir)/libtool/compile +$(curdir)/libtool/compile := $(curdir)/m4/compile $(curdir)/autoconf/compile $(curdir)/automake/compile $(curdir)/missing-macros/compile +$(curdir)/squashfs/compile := $(curdir)/lzma-old/compile +$(curdir)/squashfs4/compile := $(curdir)/xz/compile $(curdir)/zlib/compile +$(curdir)/quilt/compile := $(curdir)/autoconf/compile $(curdir)/findutils/compile +$(curdir)/autoconf/compile := $(curdir)/m4/compile +$(curdir)/automake/compile := $(curdir)/m4/compile $(curdir)/autoconf/compile $(curdir)/pkg-config/compile $(curdir)/xz/compile +$(curdir)/gmp/compile := $(curdir)/libtool/compile +$(curdir)/mpc/compile := $(curdir)/mpfr/compile $(curdir)/gmp/compile +$(curdir)/mpfr/compile := $(curdir)/gmp/compile +$(curdir)/mtd-utils/compile := $(curdir)/libtool/compile $(curdir)/e2fsprogs/compile $(curdir)/zlib/compile +$(curdir)/mklibs/compile := $(curdir)/libtool/compile +$(curdir)/qemu/compile := $(curdir)/e2fsprogs/compile $(curdir)/zlib/compile +$(curdir)/upslug2/compile := $(curdir)/libtool/compile +$(curdir)/mm-macros/compile := $(curdir)/libtool/compile +$(curdir)/missing-macros/compile := $(curdir)/autoconf/compile +$(curdir)/e2fsprogs/compile := $(curdir)/libtool/compile +$(curdir)/libelf/compile := $(curdir)/libtool/compile +$(curdir)/sdcc/compile := $(curdir)/bison/compile +$(curdir)/b43-tools/compile := $(curdir)/bison/compile +$(curdir)/padjffs2/compile := $(curdir)/findutils/compile +$(curdir)/isl/compile := $(curdir)/gmp/compile +$(curdir)/bc/compile := $(curdir)/bison/compile +$(curdir)/findutils/compile := $(curdir)/bison/compile +$(curdir)/gengetopt/compile := $(curdir)/libtool/compile +$(curdir)/patchelf/compile := $(curdir)/libtool/compile +$(curdir)/dosfstools/compile := $(curdir)/autoconf/compile $(curdir)/automake/compile +$(curdir)/libressl/compile := $(curdir)/pkg-config/compile +$(curdir)/mkimage/compile += $(curdir)/libressl/compile +$(curdir)/firmware-utils/compile += $(curdir)/libressl/compile $(curdir)/zlib/compile +$(curdir)/cmake/compile += $(curdir)/libressl/compile +$(curdir)/zlib/compile := $(curdir)/cmake/compile +$(curdir)/wrt350nv2-builder/compile := $(curdir)/zlib/compile +$(curdir)/lzma-old/compile := $(curdir)/zlib/compile +$(curdir)/make-ext4fs/compile := $(curdir)/zlib/compile + +ifneq ($(HOST_OS),Linux) + tools-y += coreutils endif -# builddir dependencies -$(curdir)/bison/compile := $(curdir)/flex/install -$(curdir)/pkg-config/compile := $(curdir)/sed/install -$(curdir)/libtool/compile := $(curdir)/sed/install -$(curdir)/squashfs/compile := $(curdir)/lzma-old/install -$(curdir)/squashfs4/compile := $(curdir)/xz/install -$(curdir)/quilt/compile := $(curdir)/sed/install $(curdir)/autoconf/install -$(curdir)/dtc/compile := $(curdir)/bison/install -$(curdir)/autoconf/compile := $(curdir)/m4/install $(curdir)/libtool/install -$(curdir)/automake/compile := $(curdir)/m4/install $(curdir)/autoconf/install $(curdir)/pkg-config/install -$(curdir)/gmp/compile := $(curdir)/automake/install -$(curdir)/mpc/compile := $(curdir)/mpfr/install $(curdir)/gmp/install -$(curdir)/mpfr/compile := $(curdir)/gmp/install -$(curdir)/ppl/compile := $(curdir)/gmp/install -$(curdir)/cloog/compile := $(curdir)/ppl/install -$(curdir)/mtd-utils/compile := $(curdir)/e2fsprogs/install $(curdir)/xz/install -$(curdir)/mkimage/compile := $(curdir)/sed/install -$(curdir)/qemu/compile := $(curdir)/e2fsprogs/install -$(curdir)/upslug2/compile := $(curdir)/automake/install -$(curdir)/mm-macros/compile := $(curdir)/automake/install -$(curdir)/xorg-macros/compile := $(curdir)/automake/install -$(curdir)/xfce-macros/compile := $(curdir)/automake/install -$(curdir)/missing-macros/compile := $(curdir)/automake/install -$(curdir)/e2fsprogs/compile := $(curdir)/automake/install -$(curdir)/libelf/compile := $(curdir)/automake/install - -ifneq ($(CONFIG_CCACHE),) -$(foreach tool, $(tools-y), $(eval $(curdir)/$(tool)/compile += $(curdir)/ccache/install)) +ifneq ($(CONFIG_CCACHE)$(CONFIG_SDK),) +$(foreach tool, $(filter-out xz patch,$(tools-y)), $(eval $(curdir)/$(tool)/compile += $(curdir)/ccache/compile)) tools-y += ccache endif +# in case there is no patch tool on the host we need to make patch tool a +# dependency for tools which have patches directory +$(foreach tool, $(tools-y), $(if $(wildcard $(curdir)/$(tool)/patches),$(eval $(curdir)/$(tool)/compile += $(curdir)/patch/compile))) + +$(foreach tool, $(filter-out xz,$(tools-y)), $(eval $(curdir)/$(tool)/compile += $(curdir)/xz/compile)) + +# make any tool depend on tar, xz and patch to ensure that archives can be unpacked and patched properly +tools-core := tar xz patch + +$(foreach tool, $(tools-y), $(eval $(curdir)/$(tool)/compile += $(patsubst %,$(curdir)/%/compile,$(tools-core)))) +tools-y += $(tools-core) + +# make core tools depend on sed and flock +$(foreach tool, $(tools-core), $(eval $(curdir)/$(tool)/compile += $(curdir)/sed/compile)) + +$(curdir)/sed/compile := $(curdir)/flock/compile +tools-y += flock sed + +$(curdir)/autoremove := 1 $(curdir)/builddirs := $(tools-y) $(tools-dep) $(tools-) $(curdir)/builddirs-default := $(tools-y) +ifdef CHECK_ALL +$(curdir)/builddirs-check:=$($(curdir)/builddirs) +$(curdir)/builddirs-download:=$($(curdir)/builddirs) +endif + ifndef DUMP_TARGET_DB define PrepareStaging @for dir in $(1); do ( \ @@ -90,30 +137,17 @@ $(STAGING_DIR_HOST)/.prepared: $(TMP_DIR)/.build ln -sf lib $(STAGING_DIR_HOST)/lib64 touch $@ - -define PrepareCommand -$(STAGING_DIR_HOST)/bin/$(1): $(STAGING_DIR)/.prepared - @mkdir -p "$$(dir $$@)"; rm -f "$$@" - @export FILE="$$$$(which $(2) 2>/dev/null | grep -v 'not found' | head -n1)"; [ -n "$$$$FILE" ] || { \ - echo "Command $(1) not found."; false; \ - }; ln -s "$$$$FILE" "$$@" - -endef endif -$(eval $(call PrepareCommand,find,gfind find)) -$(eval $(call PrepareCommand,md5sum,md5sum $(SCRIPT_DIR)/md5sum)) -$(eval $(call PrepareCommand,cp,gcp cp)) -$(eval $(call PrepareCommand,stat,gstat stat)) -$(eval $(call PrepareCommand,seq,gseq seq)) - -$(curdir)/cmddeps = $(patsubst %,$(STAGING_DIR_HOST)/bin/%,find md5sum cp stat seq) -$(curdir)//prepare = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared $($(curdir)/cmddeps) -$(curdir)//compile = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared $($(curdir)/cmddeps) +$(curdir)//prepare = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared +$(curdir)//compile = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared # prerequisites for the individual targets $(curdir)/ := .config prereq -$(curdir)//install = $(1)/compile -$(eval $(call stampfile,$(curdir),tools,install,,CONFIG_CCACHE CONFIG_powerpc CONFIG_GCC_VERSION_4_5 CONFIG_GCC_USE_GRAPHITE CONFIG_TARGET_orion_generic)) +$(curdir)/install: $(curdir)/compile + +tools_enabled = $(foreach tool,$(sort $(tools-y) $(tools-)),$(if $(filter $(tool),$(tools-y)),y,n)) +$(eval $(call stampfile,$(curdir),tools,compile,,_$(subst $(space),,$(tools_enabled)))) +$(eval $(call stampfile,$(curdir),tools,check,$(TMP_DIR)/.build)) $(eval $(call subdir,$(curdir))) diff --git a/tools/autoconf/Makefile b/tools/autoconf/Makefile index f5d22c3ff85..6eb64d77d51 100644 --- a/tools/autoconf/Makefile +++ b/tools/autoconf/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006 OpenWrt.org +# Copyright (C) 2006-2015 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,19 +7,19 @@ include $(TOPDIR)/rules.mk PKG_NAME:=autoconf -PKG_VERSION:=2.68 +PKG_VERSION:=2.69 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNU/autoconf -PKG_MD5SUM:=864d785215aa60d627c91fcb21b05b07 +PKG_HASH:=64ebcec9f8ac5b2487125a86a7760d2591ac9e1d3dbd59489633f9de62a57684 include $(INCLUDE_DIR)/host-build.mk -define Host/Configure - $(call Host/Configure/Default,\ - --datarootdir=$(STAGING_DIR_HOST)/share \ - ) -endef +HOST_CONFIGURE_ARGS += \ + --datarootdir=$(STAGING_DIR_HOST)/share + +HOST_CONFIGURE_VARS += \ + PERL="/usr/bin/env perl" define Host/Compile export SHELL="$(BASH)"; $(MAKE) -C $(HOST_BUILD_DIR) diff --git a/tools/autoconf/patches/000-relocatable.patch b/tools/autoconf/patches/000-relocatable.patch index 0b83a2b44c3..12e94ae9a15 100644 --- a/tools/autoconf/patches/000-relocatable.patch +++ b/tools/autoconf/patches/000-relocatable.patch @@ -1,6 +1,6 @@ --- a/bin/autoheader.in +++ b/bin/autoheader.in -@@ -29,7 +29,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; +@@ -28,7 +28,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; BEGIN { @@ -10,7 +10,7 @@ unshift @INC, "$pkgdatadir"; # Override SHELL. On DJGPP SHELL may not be set to a shell -@@ -51,7 +52,7 @@ use strict; +@@ -50,7 +51,7 @@ use strict; use vars qw ($config_h %verbatim %symbol); # Lib files. @@ -21,7 +21,21 @@ my @prepend_include; --- a/bin/autom4te.in +++ b/bin/autom4te.in -@@ -25,7 +25,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; +@@ -1,10 +1,12 @@ +-#! @PERL@ -w ++#! @PERL@ + # -*- perl -*- + # @configure_input@ + + eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' + if 0; + ++$^W = 1; ++ + # autom4te - Wrapper around M4 libraries. + # Copyright (C) 2001-2003, 2005-2012 Free Software Foundation, Inc. + +@@ -24,7 +26,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; BEGIN { @@ -31,7 +45,7 @@ unshift @INC, $pkgdatadir; # Override SHELL. On DJGPP SHELL may not be set to a shell -@@ -45,7 +46,8 @@ use File::Basename; +@@ -44,7 +47,8 @@ use File::Basename; use strict; # Data directory. @@ -41,7 +55,7 @@ # $LANGUAGE{LANGUAGE} -- Automatic options for LANGUAGE. my %language; -@@ -88,7 +90,7 @@ my @include; +@@ -87,7 +91,7 @@ my @include; my $freeze = 0; # $M4. @@ -50,7 +64,7 @@ # Some non-GNU m4's don't reject the --help option, so give them /dev/null. fatal "need GNU m4 1.4 or later: $m4" if system "$m4 --help </dev/null 2>&1 | grep reload-state >/dev/null"; -@@ -270,6 +272,12 @@ sub load_configuration ($) +@@ -269,6 +273,12 @@ sub load_configuration ($) my @words = shellwords ($_); my $type = shift @words; @@ -65,7 +79,21 @@ fatal "$file:$.: end-language missing for: $lang" --- a/bin/autoreconf.in +++ b/bin/autoreconf.in -@@ -27,7 +27,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; +@@ -1,10 +1,12 @@ +-#! @PERL@ -w ++#! @PERL@ + # -*- perl -*- + # @configure_input@ + + eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' + if 0; + ++$^W = 1; ++ + # autoreconf - install the GNU Build System in a directory tree + # Copyright (C) 1994, 1999-2012 Free Software Foundation, Inc. + +@@ -26,7 +28,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; BEGIN { @@ -75,7 +103,7 @@ unshift @INC, $pkgdatadir; # Override SHELL. On DJGPP SHELL may not be set to a shell -@@ -107,9 +108,9 @@ Written by David J. MacKenzie and Akim D +@@ -106,9 +109,9 @@ Written by David J. MacKenzie and Akim D "; # Lib files. @@ -90,8 +118,18 @@ my $libtoolize = $ENV{'LIBTOOLIZE'} || 'libtoolize'; --- a/bin/autoscan.in +++ b/bin/autoscan.in -@@ -26,7 +26,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; +@@ -1,4 +1,4 @@ +-#! @PERL@ -w ++#! @PERL@ + # -*- perl -*- + # @configure_input@ +@@ -23,9 +23,12 @@ + eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' + if 0; + ++$^W = 1; ++ BEGIN { - my $pkgdatadir = $ENV{'autom4te_perllibdir'} || '@pkgdatadir@'; @@ -100,7 +138,7 @@ unshift @INC, $pkgdatadir; # Override SHELL. On DJGPP SHELL may not be set to a shell -@@ -92,10 +93,10 @@ my $configure_scan = 'configure.scan'; +@@ -91,10 +94,10 @@ my $configure_scan = 'configure.scan'; my $log; # Autoconf and lib files. @@ -115,8 +153,18 @@ # ----- --- a/bin/autoupdate.in +++ b/bin/autoupdate.in -@@ -27,7 +27,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; +@@ -1,4 +1,4 @@ +-#! @PERL@ -w ++#! @PERL@ + # -*- perl -*- + # @configure_input@ +@@ -24,9 +24,12 @@ + eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' + if 0; + ++$^W = 1; ++ BEGIN { - my $pkgdatadir = $ENV{'autom4te_perllibdir'} || '@pkgdatadir@'; @@ -125,7 +173,7 @@ unshift @INC, $pkgdatadir; # Override SHELL. On DJGPP SHELL may not be set to a shell -@@ -51,10 +52,10 @@ my $autom4te = $ENV{'AUTOM4TE'} || '@bin +@@ -50,10 +53,10 @@ my $autom4te = $ENV{'AUTOM4TE'} || '@bin my $autoconf = "$autom4te --language=autoconf"; # We need to find m4sugar. my @prepend_include; @@ -140,7 +188,21 @@ # $HELP --- a/bin/ifnames.in +++ b/bin/ifnames.in -@@ -31,7 +31,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; +@@ -1,10 +1,12 @@ +-#! @PERL@ -w ++#! @PERL@ + # -*- perl -*- + # @configure_input@ + + eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' + if 0; + ++$^W = 1; ++ + # ifnames - print the identifiers used in C preprocessor conditionals + + # Copyright (C) 1994-1995, 1999-2003, 2005-2012 Free Software +@@ -31,7 +33,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; BEGIN { @@ -152,7 +214,7 @@ # Override SHELL. On DJGPP SHELL may not be set to a shell --- a/bin/autoconf.as +++ b/bin/autoconf.as -@@ -85,7 +85,11 @@ exit_missing_arg=' +@@ -84,7 +84,11 @@ exit_missing_arg=' # restore font-lock: ' # Variables. diff --git a/tools/autoconf/patches/001-no_emacs_lib.patch b/tools/autoconf/patches/001-no_emacs_lib.patch index 02e115d48be..35c51642e84 100644 --- a/tools/autoconf/patches/001-no_emacs_lib.patch +++ b/tools/autoconf/patches/001-no_emacs_lib.patch @@ -1,6 +1,6 @@ --- a/lib/Makefile.am +++ b/lib/Makefile.am -@@ -16,7 +16,7 @@ +@@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -11,7 +11,7 @@ --- a/lib/Makefile.in +++ b/lib/Makefile.in -@@ -226,7 +226,7 @@ target_alias = @target_alias@ +@@ -225,7 +225,7 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ diff --git a/tools/autoconf/patches/002-musl_host_fixup.patch b/tools/autoconf/patches/002-musl_host_fixup.patch new file mode 100644 index 00000000000..4dcb1ec3c12 --- /dev/null +++ b/tools/autoconf/patches/002-musl_host_fixup.patch @@ -0,0 +1,24 @@ +--- a/build-aux/config.sub ++++ b/build-aux/config.sub +@@ -122,9 +122,9 @@ esac + # Here we must recognize all the valid KERNEL-OS combinations. + maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` + case $maybe_os in +- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ +- linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ +- knetbsd*-gnu* | netbsd*-gnu* | \ ++ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-musl* | \ ++ linux-newlib* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ ++ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os +@@ -1360,7 +1360,7 @@ case $os in + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ +- | -linux-newlib* | -linux-uclibc* \ ++ | -linux-musl* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ diff --git a/tools/automake/Makefile b/tools/automake/Makefile index c30a9900e61..c016f1d76a6 100644 --- a/tools/automake/Makefile +++ b/tools/automake/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006-2012 OpenWrt.org +# Copyright (C) 2006-2015 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,25 +7,40 @@ include $(TOPDIR)/rules.mk PKG_NAME:=automake -PKG_VERSION:=1.11.1 +PKG_CPE_ID:=cpe:/a:gnu:automake +PKG_VERSION:=1.15.1 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNU/automake -PKG_MD5SUM:=c2972c4d9b3e29c03d5f2af86249876f +PKG_HASH:=af6ba39142220687c500f79b4aa2f181d9b24e4f8d8ec497cea4ba26c64bedaf include $(INCLUDE_DIR)/host-build.mk -HOST_CONFIGURE_ARGS += --datarootdir=$(STAGING_DIR_HOST)/share -HOST_CONFIGURE_VARS += am_cv_prog_PERL_ithreads=no +HOST_CONFIGURE_ARGS += \ + --datarootdir=$(STAGING_DIR_HOST)/share \ + --disable-silent-rules + +HOST_CONFIGURE_VARS += \ + PERL="/usr/bin/env perl" \ + am_cv_prog_PERL_ithreads=no + +define Host/Configure + (cd $(HOST_BUILD_DIR); $(AM_TOOL_PATHS) STAGING_DIR="" ./bootstrap) + $(call Host/Configure/Default) +endef define Host/Install + # remove old automake resources to avoid version conflicts + rm -rf $(STAGING_DIR_HOST)/share/aclocal-[0-9]* + rm -rf $(STAGING_DIR_HOST)/share/automake-[0-9]* $(MAKE) -C $(HOST_BUILD_DIR) install mv $(STAGING_DIR_HOST)/bin/aclocal $(STAGING_DIR_HOST)/bin/aclocal.real $(INSTALL_BIN) ./files/aclocal $(STAGING_DIR_HOST)/bin ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.9 ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.10 ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.11 - ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.11.1 + ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.11.6 + ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.15 endef define Host/Clean diff --git a/tools/automake/patches/000-relocatable.patch b/tools/automake/patches/000-relocatable.patch index 3255b97518f..d05b25e61c2 100644 --- a/tools/automake/patches/000-relocatable.patch +++ b/tools/automake/patches/000-relocatable.patch @@ -1,18 +1,42 @@ ---- a/aclocal.in -+++ b/aclocal.in -@@ -28,7 +28,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; +--- a/lib/Automake/Config.in ++++ b/lib/Automake/Config.in +@@ -32,7 +32,7 @@ our $PACKAGE = '@PACKAGE@'; + our $PACKAGE_BUGREPORT = '@PACKAGE_BUGREPORT@'; + our $VERSION = '@VERSION@'; + our $RELEASE_YEAR = '@RELEASE_YEAR@'; +-our $libdir = '@datadir@/@PACKAGE@-@APIVERSION@'; ++our $libdir = $ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@'; + + our $perl_threads = 0; + # We need at least this version for CLONE support. +--- a/bin/aclocal.in ++++ b/bin/aclocal.in +@@ -1,10 +1,12 @@ +-#!@PERL@ -w ++#!@PERL@ + # -*- perl -*- + # @configure_input@ + + eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' + if 0; + ++$^W = 1; ++ + # aclocal - create aclocal.m4 by scanning configure.ac + + # Copyright (C) 1996-2017 Free Software Foundation, Inc. +@@ -27,7 +29,7 @@ eval 'case $# in 0) exec @PERL@ -S "$0"; BEGIN { -- my $perllibdir = $ENV{'perllibdir'} || '@datadir@/@PACKAGE@-@APIVERSION@'; -+ my $perllibdir = $ENV{'perllibdir'} || -+ ($ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@'); - unshift @INC, (split '@PATH_SEPARATOR@', $perllibdir); +- @Aclocal::perl_libdirs = ('@datadir@/@PACKAGE@-@APIVERSION@') ++ @Aclocal::perl_libdirs = ($ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@') + unless @Aclocal::perl_libdirs; + unshift @INC, @Aclocal::perl_libdirs; } - -@@ -57,8 +58,8 @@ $perl_threads = 0; - # @system_includes can be augmented with the `dirlist' file. Also - # --acdir will reset both @automake_includes and @system_includes. +@@ -69,8 +71,8 @@ $perl_threads = 0; + # ACLOCAL_PATH environment variable, and reset with the '--system-acdir' + # option. my @user_includes = (); -my @automake_includes = ("@datadir@/aclocal-$APIVERSION"); -my @system_includes = ('@datadir@/aclocal'); @@ -21,26 +45,52 @@ # Whether we should copy M4 file in $user_includes[0]. my $install = 0; ---- a/automake.in -+++ b/automake.in -@@ -31,7 +31,8 @@ package Language; +--- a/bin/automake.in ++++ b/bin/automake.in +@@ -1,10 +1,12 @@ +-#!@PERL@ -w ++#!@PERL@ + # -*- perl -*- + # @configure_input@ + + eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac' + if 0; + ++$^W = 1; ++ + # automake - create Makefile.in from Makefile.am + # Copyright (C) 1994-2017 Free Software Foundation, Inc. + +@@ -31,7 +33,7 @@ use strict; BEGIN { -- my $perllibdir = $ENV{'perllibdir'} || '@datadir@/@PACKAGE@-@APIVERSION@'; -+ my $perllibdir = $ENV{'perllibdir'} || -+ ($ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@'); - unshift @INC, (split '@PATH_SEPARATOR@', $perllibdir); +- @Automake::perl_libdirs = ('@datadir@/@PACKAGE@-@APIVERSION@') ++ @Automake::perl_libdirs = ($ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@') + unless @Automake::perl_libdirs; + unshift @INC, @Automake::perl_libdirs; - # Override SHELL. This is required on DJGPP so that system() uses ---- a/lib/Automake/Config.in -+++ b/lib/Automake/Config.in -@@ -28,7 +28,7 @@ our @EXPORT = qw ($APIVERSION $PACKAGE $ - our $APIVERSION = '@APIVERSION@'; - our $PACKAGE = '@PACKAGE@'; - our $VERSION = '@VERSION@'; --our $libdir = '@datadir@/@PACKAGE@-@APIVERSION@'; -+our $libdir = $ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@'; - our $perl_threads = @PERL_THREADS@; +--- a/t/wrap/aclocal.in ++++ b/t/wrap/aclocal.in +@@ -1,6 +1,8 @@ +-#!@PERL@ -w ++#!@PERL@ + # @configure_input@ + ++$^W = 1; ++ + # Copyright (C) 2012-2017 Free Software Foundation, Inc. + + # This program is free software; you can redistribute it and/or modify +--- a/t/wrap/automake.in ++++ b/t/wrap/automake.in +@@ -1,6 +1,8 @@ +-#!@PERL@ -w ++#!@PERL@ + # @configure_input@ + ++$^W = 1; ++ + # Copyright (C) 2012-2017 Free Software Foundation, Inc. - 1;; + # This program is free software; you can redistribute it and/or modify diff --git a/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch b/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch index cc1f49d519e..ad019ddd1ae 100644 --- a/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch +++ b/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch @@ -1,15 +1,15 @@ ---- a/aclocal.in -+++ b/aclocal.in -@@ -310,6 +310,12 @@ sub scan_m4_dirs ($@) +--- a/bin/aclocal.in ++++ b/bin/aclocal.in +@@ -356,6 +356,12 @@ sub scan_m4_dirs ($$@) foreach my $m4dir (@dirlist) { + if (! -d $m4dir) -+ { -+ msg ('override', "warning: skipping not existing directory `$m4dir'"); -+ next; -+ } ++ { ++ msg ('override', "warning: skipping not existing directory `$m4dir'"); ++ next; ++ } + if (! opendir (DIR, $m4dir)) { - fatal "couldn't open directory `$m4dir': $!"; + # TODO: maybe avoid complaining only if errno == ENONENT? diff --git a/tools/automake/patches/200-do-not-override-silent-rules.patch b/tools/automake/patches/200-do-not-override-silent-rules.patch new file mode 100644 index 00000000000..e8ba8c5ca54 --- /dev/null +++ b/tools/automake/patches/200-do-not-override-silent-rules.patch @@ -0,0 +1,13 @@ +diff -ruN automake-1.15/m4/silent.m4 automake-1.15.mod/m4/silent.m4 +--- automake-1.15/m4/silent.m4 2014-12-30 22:53:05.000000000 +0100 ++++ automake-1.15.mod/m4/silent.m4 2015-03-11 12:00:26.280586399 +0100 +@@ -41,7 +41,8 @@ + else + am_cv_make_support_nested_variables=no + fi]) +-if test $am_cv_make_support_nested_variables = yes; then ++#if test $am_cv_make_support_nested_variables = yes; then ++if false; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' diff --git a/tools/b43-tools/Makefile b/tools/b43-tools/Makefile new file mode 100644 index 00000000000..a99b0c9e53d --- /dev/null +++ b/tools/b43-tools/Makefile @@ -0,0 +1,50 @@ +# +# Copyright (C) 2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=b43-tools +PKG_DATE:=2017-09-13 + +PKG_SOURCE_URL:=https://github.com/mbuesch/b43-tools.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_SUBDIR:=$(PKG_NAME) +PKG_SOURCE_VERSION:=27892ef741e7f1d08cb939744f8b8f5dac7b04ae +PKG_MIRROR_HASH:=f914c36ac566e9e3b5a3a04de16ddb014fcad6a1cf25cdd8e4825c708d28d3f4 +HOST_BUILD_DIR=$(BUILD_DIR_HOST)/$(PKG_NAME) + +include $(INCLUDE_DIR)/host-build.mk + + +define Host/Compile + +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR)/fwcutter \ + CFLAGS="$(HOST_CFLAGS) -include endian.h" \ + $(HOST_MAKE_FLAGS) \ + $(1) QUIET_SPARSE=: + +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR)/assembler \ + CFLAGS="$(HOST_CFLAGS) -include endian.h" \ + $(HOST_MAKE_FLAGS) \ + LDFLAGS= \ + $(1) QUIET_SPARSE=: +endef + +define Host/Install + $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin + $(INSTALL_BIN) $(HOST_BUILD_DIR)/fwcutter/b43-fwcutter $(STAGING_DIR_HOST)/bin/ + $(INSTALL_BIN) $(HOST_BUILD_DIR)/assembler/b43-asm $(STAGING_DIR_HOST)/bin/ + $(INSTALL_BIN) $(HOST_BUILD_DIR)/assembler/b43-asm.bin $(STAGING_DIR_HOST)/bin/ + $(INSTALL_BIN) ./files/b43-fwsquash.py $(STAGING_DIR_HOST)/bin/ +endef + +define Host/Clean + rm -f $(STAGING_DIR_HOST)/bin/b43-fwcutter + rm -f $(STAGING_DIR_HOST)/bin/b43-asm + rm -f $(STAGING_DIR_HOST)/bin/b43-asm.bin + rm -f $(STAGING_DIR_HOST)/bin/b43-fwsquash.py +endef + +$(eval $(call HostBuild)) diff --git a/tools/b43-tools/files/b43-fwsquash.py b/tools/b43-tools/files/b43-fwsquash.py new file mode 100755 index 00000000000..2946d7c3c32 --- /dev/null +++ b/tools/b43-tools/files/b43-fwsquash.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +# +# b43 firmware file squasher +# Removes unnecessary firmware files +# +# Copyright (c) 2009 Michael Buesch <mb@bu3sch.de> +# +# Licensed under the GNU/GPL version 2 or (at your option) any later version. +# + +import sys +import os + +def usage(): + print("Usage: %s PHYTYPES COREREVS /path/to/extracted/firmware" % sys.argv[0]) + print("") + print("PHYTYPES is a comma separated list of:") + print("A => A-PHY") + print("AG => Dual A-PHY G-PHY") + print("G => G-PHY") + print("LP => LP-PHY") + print("N => N-PHY") + print("HT => HT-PHY") + print("LCN => LCN-PHY") + print("LCN40 => LCN40-PHY") + print("AC => AC-PHY") + print("") + print("COREREVS is a comma separated list of core revision numbers.") + +if len(sys.argv) != 4: + usage() + sys.exit(1) + +phytypes = sys.argv[1] +corerevs = sys.argv[2] +fwpath = sys.argv[3] + +phytypes = phytypes.split(',') +try: + corerevs = map(lambda r: int(r), corerevs.split(',')) +except ValueError: + print("ERROR: \"%s\" is not a valid COREREVS string\n" % corerevs) + usage() + sys.exit(1) + + +fwfiles = os.listdir(fwpath) +fwfiles = filter(lambda str: str.endswith(".fw"), fwfiles) +if not fwfiles: + print("ERROR: No firmware files found in %s" % fwpath) + sys.exit(1) + +required_fwfiles = [] + +def revs_match(revs_a, revs_b): + for rev in revs_a: + if rev in revs_b: + return True + return False + +def phytypes_match(types_a, types_b): + for type in types_a: + type = type.strip().upper() + if type in types_b: + return True + return False + +revmapping = { + "ucode2.fw" : ( (2,3,), ("G",), ), + "ucode4.fw" : ( (4,), ("G",), ), + "ucode5.fw" : ( (5,6,7,8,9,10,), ("G","A","AG",), ), + "ucode11.fw" : ( (11,12,), ("N",), ), + "ucode13.fw" : ( (13,), ("LP","G",), ), + "ucode14.fw" : ( (14,), ("LP",), ), + "ucode15.fw" : ( (15,), ("LP",), ), + "ucode16_mimo.fw" : ( (16,17,18,19,23,), ("N",), ), +# "ucode16_lp.fw" : ( (16,17,18,19,), ("LP",), ), + "ucode24_lcn.fw" : ( (24,), ("LCN",), ), + "ucode25_mimo.fw" : ( (25,28,), ("N",), ), + "ucode25_lcn.fw" : ( (25,28,), ("LCN",), ), + "ucode26_mimo.fw" : ( (26,), ("HT",), ), + "ucode29_mimo.fw" : ( (29,), ("HT",), ), + "ucode30_mimo.fw" : ( (30,), ("N",), ), + "ucode33_lcn40.fw" : ( (33,), ("LCN40",), ), + "ucode40.fw" : ( (40,), ("AC",), ), + "ucode42.fw" : ( (42,), ("AC",), ), + "pcm4.fw" : ( (1,2,3,4,), ("G",), ), + "pcm5.fw" : ( (5,6,7,8,9,10,), ("G","A","AG",), ), +} + +initvalmapping = { + "a0g1initvals5.fw" : ( (5,6,7,8,9,10,), ("AG",), ), + "a0g0initvals5.fw" : ( (5,6,7,8,9,10,), ("A", "AG",), ), + "b0g0initvals2.fw" : ( (2,4,), ("G",), ), + "b0g0initvals5.fw" : ( (5,6,7,8,9,10,), ("G",), ), + "b0g0initvals13.fw" : ( (13,), ("G",), ), + "n0initvals11.fw" : ( (11,12,), ("N",), ), + "n0initvals16.fw" : ( (16,17,18,23,), ("N",), ), + "n0initvals24.fw" : ( (24,), ("N",), ), + "n0initvals25.fw" : ( (25,28,), ("N",), ), + "n16initvals30.fw" : ( (30,), ("N",), ), + "lp0initvals13.fw" : ( (13,), ("LP",), ), + "lp0initvals14.fw" : ( (14,), ("LP",), ), + "lp0initvals15.fw" : ( (15,), ("LP",), ), +# "lp0initvals16.fw" : ( (16,17,18,), ("LP",), ), + "lcn0initvals24.fw" : ( (24,), ("LCN",), ), + "ht0initvals26.fw" : ( (26,), ("HT",), ), + "ht0initvals29.fw" : ( (29,), ("HT",), ), + "lcn400initvals33.fw" : ( (33,), ("LCN40",), ), + "ac0initvals40.fw" : ( (40,), ("AC",), ), + "ac1initvals42.fw" : ( (42,), ("AC",), ), + "a0g1bsinitvals5.fw" : ( (5,6,7,8,9,10,), ("AG",), ), + "a0g0bsinitvals5.fw" : ( (5,6,7,8,9,10,), ("A", "AG"), ), + "b0g0bsinitvals5.fw" : ( (5,6,7,8,9,10,), ("G",), ), + "n0bsinitvals11.fw" : ( (11,12,), ("N",), ), + "n0bsinitvals16.fw" : ( (16,17,18,23,), ("N",), ), + "n0bsinitvals24.fw" : ( (24,), ("N",), ), + "n0bsinitvals25.fw" : ( (25,28,), ("N",), ), + "n16bsinitvals30.fw" : ( (30,), ("N",), ), + "lp0bsinitvals13.fw" : ( (13,), ("LP",), ), + "lp0bsinitvals14.fw" : ( (14,), ("LP",), ), + "lp0bsinitvals15.fw" : ( (15,), ("LP",), ), +# "lp0bsinitvals16.fw" : ( (16,17,18,), ("LP",), ), + "lcn0bsinitvals24.fw" : ( (24,), ("LCN",), ), + "ht0bsinitvals26.fw" : ( (26,), ("HT",), ), + "ht0bsinitvals29.fw" : ( (29,), ("HT",), ), + "lcn400bsinitvals33.fw" : ( (33,), ("LCN40",), ), + "ac0bsinitvals40.fw" : ( (40,), ("AC",), ), + "ac1bsinitvals42.fw" : ( (42,), ("AC",), ), +} + +for f in fwfiles: + if f in revmapping: + if revs_match(corerevs, revmapping[f][0]) and\ + phytypes_match(phytypes, revmapping[f][1]): + required_fwfiles += [f] + continue + if f in initvalmapping: + if revs_match(corerevs, initvalmapping[f][0]) and\ + phytypes_match(phytypes, initvalmapping[f][1]): + required_fwfiles += [f] + continue + print("WARNING: Firmware file %s not found in the mapping lists" % f) + +for f in fwfiles: + if f not in required_fwfiles: + print("Deleting %s" % f) + os.unlink(fwpath + '/' + f) + diff --git a/tools/b43-tools/patches/001-fw-dirname.patch b/tools/b43-tools/patches/001-fw-dirname.patch new file mode 100644 index 00000000000..1fd4c66323e --- /dev/null +++ b/tools/b43-tools/patches/001-fw-dirname.patch @@ -0,0 +1,16 @@ +--- a/fwcutter/fwcutter.c ++++ b/fwcutter/fwcutter.c +@@ -50,13 +50,8 @@ + #include "fwcutter.h" + #include "fwcutter_list.h" + +-#if defined(__DragonFly__) || defined(__FreeBSD__) +-#define V3_FW_DIRNAME "v3" +-#define V4_FW_DIRNAME "v4" +-#else + #define V3_FW_DIRNAME "b43legacy" + #define V4_FW_DIRNAME "b43" +-#endif + + static struct cmdline_args cmdargs; + diff --git a/tools/b43-tools/patches/002-no_libfl.patch b/tools/b43-tools/patches/002-no_libfl.patch new file mode 100644 index 00000000000..2e55b0803b5 --- /dev/null +++ b/tools/b43-tools/patches/002-no_libfl.patch @@ -0,0 +1,14 @@ +--- a/assembler/main.c ++++ b/assembler/main.c +@@ -1268,6 +1268,11 @@ static void initialize(void) + #endif /* YYDEBUG */ + } + ++int yywrap(void) ++{ ++ return 1; ++} ++ + int main(int argc, char **argv) + { + int err, res = 1; diff --git a/tools/bc/Makefile b/tools/bc/Makefile new file mode 100644 index 00000000000..3d505d6032f --- /dev/null +++ b/tools/bc/Makefile @@ -0,0 +1,21 @@ +# +# Copyright (C) 2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=bc +PKG_VERSION:=1.06.95 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=http://alpha.gnu.org/gnu/bc \ + http://gnualpha.uib.no/bc/ \ + http://mirrors.fe.up.pt/pub/gnu-alpha/bc/ \ + http://www.nic.funet.fi/pub/gnu/alpha/gnu/bc/ +PKG_HASH:=7ee4abbcfac03d8a6e1a8a3440558a3d239d6b858585063e745c760957725ecc + +include $(INCLUDE_DIR)/host-build.mk + +$(eval $(call HostBuild)) diff --git a/tools/bc/patches/001-no_doc.patch b/tools/bc/patches/001-no_doc.patch new file mode 100644 index 00000000000..50deee8c89d --- /dev/null +++ b/tools/bc/patches/001-no_doc.patch @@ -0,0 +1,23 @@ +diff -urN bc-1.06.95/Makefile.am bc-1.06.95.new/Makefile.am +--- bc-1.06.95/Makefile.am 2005-05-27 01:05:41.000000000 +0100 ++++ bc-1.06.95.new/Makefile.am 2013-07-09 09:33:31.521490710 +0100 +@@ -1,6 +1,6 @@ + ## Process this file with automake to produce Makefile.in + +-SUBDIRS = lib bc dc doc ++SUBDIRS = lib bc dc + + MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in \ + stamp-h $(distdir).tar.gz h/number.h depcomp missing +diff -urN bc-1.06.95/Makefile.in bc-1.06.95.new/Makefile.in +--- bc-1.06.95/Makefile.in 2006-09-05 03:39:30.000000000 +0100 ++++ bc-1.06.95.new/Makefile.in 2013-07-09 09:33:28.565490767 +0100 +@@ -149,7 +149,7 @@ + sharedstatedir = @sharedstatedir@ + sysconfdir = @sysconfdir@ + target_alias = @target_alias@ +-SUBDIRS = lib bc dc doc ++SUBDIRS = lib bc dc + MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in \ + stamp-h $(distdir).tar.gz h/number.h depcomp missing + diff --git a/tools/bison/Makefile b/tools/bison/Makefile index 01820e27550..68e06ae33b5 100644 --- a/tools/bison/Makefile +++ b/tools/bison/Makefile @@ -1,5 +1,5 @@ -# -# Copyright (C) 2008 OpenWrt.org +# +# Copyright (C) 2008-2015 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,12 +7,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=bison -PKG_VERSION:=2.4.3 +PKG_VERSION:=3.0.5 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNU/$(PKG_NAME) -PKG_MD5SUM:=c1d3ea81bc370dbd43b6f0b2cd21287e -PKG_CAT:=bzcat +PKG_HASH:=075cef2e814642e30e10e8155e93022e4a91ca38a65aa1d5467d4e969f97f338 + +HOST_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/host-build.mk @@ -21,4 +22,9 @@ define Host/Clean $(call Host/Clean/Default) endef +define Host/Install + $(call Host/Install/Default) + $(INSTALL_BIN) ./scripts/yacc $(STAGING_DIR_HOST)/bin/yacc +endef + $(eval $(call HostBuild)) diff --git a/tools/bison/patches/000-relocatable.patch b/tools/bison/patches/000-relocatable.patch deleted file mode 100644 index f83bb1e7eea..00000000000 --- a/tools/bison/patches/000-relocatable.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -77,6 +77,7 @@ MOSTLYCLEANFILES = yacc - - yacc: - echo '#! /bin/sh' >$@ -+ echo 'test -n "$$STAGING_DIR" && exec "$$STAGING_DIR/../host/bin/bison" -y "$$@"' >>$@ - echo "exec '$(bindir)/bison' -y "'"$$@"' >>$@ - chmod a+x $@ - ---- a/src/Makefile.in -+++ b/src/Makefile.in -@@ -1352,6 +1352,7 @@ uninstall-am: uninstall-binPROGRAMS unin - - yacc: - echo '#! /bin/sh' >$@ -+ echo 'test -n "$$STAGING_DIR" && exec "$$STAGING_DIR/../host/bin/bison" -y "$$@"' >>$@ - echo "exec '$(bindir)/bison' -y "'"$$@"' >>$@ - chmod a+x $@ - diff --git a/tools/bison/patches/010-intl-stub-compat.patch b/tools/bison/patches/010-intl-stub-compat.patch index 7690e10ed8b..98234209cdc 100644 --- a/tools/bison/patches/010-intl-stub-compat.patch +++ b/tools/bison/patches/010-intl-stub-compat.patch @@ -1,8 +1,8 @@ --- a/src/main.c +++ b/src/main.c -@@ -57,9 +57,9 @@ main (int argc, char *argv[]) +@@ -60,9 +60,9 @@ { - program_name = argv[0]; + set_program_name (argv[0]); setlocale (LC_ALL, ""); - (void) bindtextdomain (PACKAGE, LOCALEDIR); - (void) bindtextdomain ("bison-runtime", LOCALEDIR); @@ -11,5 +11,5 @@ + bindtextdomain ("bison-runtime", LOCALEDIR); + textdomain (PACKAGE); - uniqstrs_new (); - + { + char const *cp = getenv ("LC_CTYPE"); diff --git a/tools/bison/patches/100-fix-gets-removal.patch b/tools/bison/patches/100-fix-gets-removal.patch new file mode 100644 index 00000000000..563c12040c5 --- /dev/null +++ b/tools/bison/patches/100-fix-gets-removal.patch @@ -0,0 +1,19 @@ +diff --git a/lib/stdio.in.h b/lib/stdio.in.h +index ff7c9c8..f391832 100644 +--- a/lib/stdio.in.h ++++ b/lib/stdio.in.h +@@ -739,14 +739,6 @@ _GL_WARN_ON_USE (getline, "getline is unportable - " + # endif + #endif + +-/* It is very rare that the developer ever has full control of stdin, +- so any use of gets warrants an unconditional warning; besides, C11 +- removed it. */ +-#undef gets +-#if HAVE_RAW_DECL_GETS && !defined __cplusplus +-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); +-#endif +- + #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ + struct obstack; + /* Grow an obstack with formatted output. Return the number of diff --git a/tools/bison/scripts/yacc b/tools/bison/scripts/yacc new file mode 100755 index 00000000000..8f73e26fb13 --- /dev/null +++ b/tools/bison/scripts/yacc @@ -0,0 +1,2 @@ +#!/bin/sh +exec bison -y "$@" diff --git a/tools/ccache/Makefile b/tools/ccache/Makefile index 21123b316db..111bd91bb63 100644 --- a/tools/ccache/Makefile +++ b/tools/ccache/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006 OpenWrt.org +# Copyright (C) 2006-2015 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -8,37 +8,29 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/target.mk PKG_NAME:=ccache -PKG_VERSION:=3.1.3 +PKG_VERSION:=3.4.2 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=http://samba.org/ftp/ccache/ -PKG_MD5SUM:=b952d75e9ca37209d608ea58d84135cd -PKG_CAT:=zcat +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=https://download.samba.org/pub/ccache/ \ + https://samba.org/ftp/ccache/ +PKG_HASH:=18a8b14367d63d3d37fb6c33cba60e1b7fcd7a63d608df97c9771ae0d234fee2 include $(INCLUDE_DIR)/host-build.mk -ifneq ($(strip $(shell which ccache >/dev/null && echo found)),found) - define Host/Compile - $(MAKE) CC="$(HOSTCC_NOCACHE)" -C $(HOST_BUILD_DIR) - endef +HOST_CONFIGURE_VARS += CC="$(HOSTCC_NOCACHE)" - define Host/Clean +define Host/Install/ccache + $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin/ + $(CP) ./files/* $(STAGING_DIR_HOST)/bin/ +endef + +define Host/Clean -$(MAKE) -C $(HOST_BUILD_DIR) uninstall $(call Host/Clean/Default) - endef -else - define Host/Prepare - endef - define Host/Configure - endef - define Host/Compile - endef - define Host/Install - endef - define Host/Clean - endef - define Download - endef -endif +endef +define Host/Install + $(call Host/Install/Default) + $(call Host/Install/ccache) +endef $(eval $(call HostBuild)) diff --git a/tools/ccache/files/ccache_cc b/tools/ccache/files/ccache_cc new file mode 100755 index 00000000000..01c4ad42a21 --- /dev/null +++ b/tools/ccache/files/ccache_cc @@ -0,0 +1,2 @@ +#!/bin/sh +exec ccache "${TARGET_CC_NOCACHE}" "$@" diff --git a/tools/ccache/files/ccache_cxx b/tools/ccache/files/ccache_cxx new file mode 100755 index 00000000000..cc60eb3a13c --- /dev/null +++ b/tools/ccache/files/ccache_cxx @@ -0,0 +1,2 @@ +#!/bin/sh +exec ccache "${TARGET_CXX_NOCACHE}" "$@" diff --git a/tools/ccache/patches/100-honour-copts.patch b/tools/ccache/patches/100-honour-copts.patch new file mode 100644 index 00000000000..1916d17c60e --- /dev/null +++ b/tools/ccache/patches/100-honour-copts.patch @@ -0,0 +1,10 @@ +--- a/src/ccache.c ++++ b/src/ccache.c +@@ -1859,6 +1859,7 @@ calculate_object_hash(struct args *args, + "CPLUS_INCLUDE_PATH", + "OBJC_INCLUDE_PATH", + "OBJCPLUS_INCLUDE_PATH", // clang ++ "GCC_HONOUR_COPTS", + NULL + }; + for (const char **p = envvars; *p; ++p) { diff --git a/tools/cloog/Makefile b/tools/cloog/Makefile deleted file mode 100644 index 945258263c2..00000000000 --- a/tools/cloog/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright (C) 2009 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -include $(TOPDIR)/rules.mk - -PKG_NAME:=cloog-ppl -PKG_VERSION:=0.15.10 - -PKG_SOURCE_URL:=ftp://gcc.gnu.org/pub/gcc/infrastructure -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_MD5SUM:=04aa756179b6d850d9ffa50f61b91895 - -HOST_FIXUP:=autoreconf - -include $(INCLUDE_DIR)/host-build.mk - -unexport CFLAGS - -HOST_CONFIGURE_VARS += \ - LIBS=-lstdc++ - -HOST_CONFIGURE_ARGS += \ - --enable-static \ - --disable-shared \ - --with-ppl=$(BUILD_DIR_HOST) - -define Host/Configure - (cd $(HOST_BUILD_DIR)/$(3); \ - $(HOST_CONFIGURE_CMD) \ - $(HOST_CONFIGURE_VARS) \ - $(HOST_CONFIGURE_ARGS); \ - ) -endef - - -$(eval $(call HostBuild)) diff --git a/tools/cmake/Makefile b/tools/cmake/Makefile index d5e885ca335..340c47cb078 100644 --- a/tools/cmake/Makefile +++ b/tools/cmake/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006 OpenWrt.org +# Copyright (C) 2006-2016 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,12 +7,29 @@ include $(TOPDIR)/rules.mk PKG_NAME:=cmake -PKG_VERSION:=2.8.4 +PKG_VERSION:=3.12.1 +PKG_CPE_ID:=cpe:/a:kitware:cmake PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=http://www.cmake.org/files/v2.8/ -PKG_MD5SUM:=209b7d1d04b2e00986538d74ba764fcf +PKG_SOURCE_URL:=https://cmake.org/files/v3.12/ \ + https://fossies.org/linux/misc/ +PKG_HASH:=c53d5c2ce81d7a957ee83e3e635c8cda5dfe20c9d501a4828ee28e1615e57ab2 + +HOST_BUILD_PARALLEL:=1 +HOST_CONFIGURE_PARALLEL:=1 include $(INCLUDE_DIR)/host-build.mk +HOST_CONFIGURE_VARS += \ + MAKEFLAGS="$(HOST_JOBS)" \ + CXXFLAGS="$(HOST_CFLAGS)" + +HOST_CONFIGURE_ARGS := \ + $(if $(MAKE_JOBSERVER),--parallel="$(MAKE_JOBSERVER)") \ + --prefix=$(STAGING_DIR_HOST) + +ifneq ($(findstring c,$(OPENWRT_VERBOSE)),) + HOST_MAKE_FLAGS += VERBOSE=1 +endif + $(eval $(call HostBuild)) diff --git a/tools/cmake/patches/100-disable_qt_tests.patch b/tools/cmake/patches/100-disable_qt_tests.patch new file mode 100644 index 00000000000..a354e1cac1d --- /dev/null +++ b/tools/cmake/patches/100-disable_qt_tests.patch @@ -0,0 +1,34 @@ +--- a/Tests/RunCMake/CMakeLists.txt ++++ b/Tests/RunCMake/CMakeLists.txt +@@ -290,15 +290,6 @@ add_RunCMake_test(no_install_prefix) + add_RunCMake_test(configure_file) + add_RunCMake_test(CTestTimeoutAfterMatch) + +-find_package(Qt4 QUIET) +-find_package(Qt5Core QUIET) +-if (QT4_FOUND AND Qt5Core_FOUND AND NOT Qt5Core_VERSION VERSION_LESS 5.1.0) +- add_RunCMake_test(IncompatibleQt) +-endif() +-if (QT4_FOUND) +- add_RunCMake_test(ObsoleteQtMacros -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}) +-endif() +- + find_package(PkgConfig QUIET) + if(PKG_CONFIG_FOUND) + add_RunCMake_test(FindPkgConfig) +--- a/Tests/CMakeLists.txt ++++ b/Tests/CMakeLists.txt +@@ -435,13 +435,6 @@ if(BUILD_TESTING) + + list(APPEND TEST_BUILD_DIRS ${CMake_TEST_INSTALL_PREFIX}) + +- if(NOT DEFINED CMake_TEST_Qt4) +- set(CMake_TEST_Qt4 1) +- endif() +- if(CMake_TEST_Qt4 AND NOT QT4_FOUND) +- find_package(Qt4 QUIET) +- endif() +- + if(CMake_TEST_Qt4 AND QT4_FOUND) + # test whether the Qt4 which has been found works, on some machines + # which run nightly builds there were errors like "wrong file format" diff --git a/tools/cmake/patches/110-libarchive-fix-libressl-compat.patch b/tools/cmake/patches/110-libarchive-fix-libressl-compat.patch new file mode 100644 index 00000000000..ba6565b6af0 --- /dev/null +++ b/tools/cmake/patches/110-libarchive-fix-libressl-compat.patch @@ -0,0 +1,11 @@ +--- a/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h ++++ b/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h +@@ -28,7 +28,7 @@ + #include <openssl/evp.h> + #include <openssl/opensslv.h> + +-#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + #include <stdlib.h> /* malloc, free */ + #include <string.h> /* memset */ + static inline EVP_MD_CTX *EVP_MD_CTX_new(void) diff --git a/tools/cmake/patches/120-curl-fix-libressl-linking.patch b/tools/cmake/patches/120-curl-fix-libressl-linking.patch new file mode 100644 index 00000000000..20c5052cce1 --- /dev/null +++ b/tools/cmake/patches/120-curl-fix-libressl-linking.patch @@ -0,0 +1,37 @@ +From: Jo-Philipp Wich <jo@mein.io> +Date: Wed, 11 Jan 2017 03:36:04 +0100 +Subject: [PATCH] cmcurl: link librt + +When cmake is linked against LibreSSL, there might be an indirect +dependency on librt on certain systems if LibreSSL's libcrypto uses +clock_gettime() from librt: + + [ 28%] Linking C executable LIBCURL + .../lib/libcrypto.a(getentropy_linux.o): In function `getentropy_fallback': + getentropy_linux.c:(.text+0x16d): undefined reference to `clock_gettime' + getentropy_linux.c:(.text+0x412): undefined reference to `clock_gettime' + collect2: error: ld returned 1 exit status + make[5]: *** [Utilities/cmcurl/LIBCURL] Error 1 + +Modify the cmcurl CMakeLists.txt to check for clock_gettime() in librt +and unconditionally link the rt library when the symbol is found. + +Signed-off-by: Jo-Philipp Wich <jo@mein.io> +--- +--- a/Utilities/cmcurl/CMakeLists.txt ++++ b/Utilities/cmcurl/CMakeLists.txt +@@ -452,6 +452,14 @@ if(CMAKE_USE_OPENSSL) + set(USE_OPENSSL ON) + set(HAVE_LIBCRYPTO ON) + set(HAVE_LIBSSL ON) ++ check_library_exists("rt" clock_gettime "" HAVE_LIBRT) ++ if(HAVE_LIBRT) ++ list(APPEND OPENSSL_LIBRARIES rt) ++ endif() ++ check_library_exists("pthread" pthread_once "" HAVE_PTHREAD) ++ if(HAVE_PTHREAD) ++ list(APPEND OPENSSL_LIBRARIES pthread) ++ endif() + list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES}) + include_directories(${OPENSSL_INCLUDE_DIR}) + set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) diff --git a/tools/cmake/patches/130-bootstrap_parallel_make_flag.patch b/tools/cmake/patches/130-bootstrap_parallel_make_flag.patch new file mode 100644 index 00000000000..375bc5d979c --- /dev/null +++ b/tools/cmake/patches/130-bootstrap_parallel_make_flag.patch @@ -0,0 +1,14 @@ +--- a/bootstrap ++++ b/bootstrap +@@ -1163,7 +1163,10 @@ int main(){ printf("1%c", (char)0x0a); r + ' > "test.c" + cmake_original_make_flags="${cmake_make_flags}" + if [ "x${cmake_parallel_make}" != "x" ]; then +- cmake_make_flags="${cmake_make_flags} -j ${cmake_parallel_make}" ++ case "$cmake_paralle_make" in ++ [0-9]*) cmake_parallel_make="-j ${cmake_parallel_make}";; ++ esac ++ cmake_make_flags="${cmake_make_flags} ${cmake_parallel_make}" + fi + for a in ${cmake_make_processors}; do + if [ -z "${cmake_make_processor}" ] && cmake_try_make "${a}" "${cmake_make_flags}" >> ../cmake_bootstrap.log 2>&1; then diff --git a/tools/cmake/patches/140-libarchive-fix-libressl.patch b/tools/cmake/patches/140-libarchive-fix-libressl.patch new file mode 100644 index 00000000000..ad8a0969a8f --- /dev/null +++ b/tools/cmake/patches/140-libarchive-fix-libressl.patch @@ -0,0 +1,37 @@ +From 5da00ad75b09e262774ec3675bbe4d5a4502a852 Mon Sep 17 00:00:00 2001 +From: Bernard Spil <brnrd@FreeBSD.org> +Date: Sun, 1 Apr 2018 23:01:44 +0200 +Subject: [PATCH] fix build with LibreSSL 2.7 + +LibreSSL 2.7 adds OpenSSL 1.1 API leading to conflicts on method names + +See also: https://bugs.freebsd.org/226853 +Signed-off-by: Bernard Spil <brnrd@FreeBSD.org> +--- + libarchive/archive_openssl_hmac_private.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h ++++ b/Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h +@@ -28,7 +28,8 @@ + #include <openssl/hmac.h> + #include <openssl/opensslv.h> + +-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || \ ++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) + #include <stdlib.h> /* malloc, free */ + #include <string.h> /* memset */ + static inline HMAC_CTX *HMAC_CTX_new(void) +--- a/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h ++++ b/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h +@@ -28,7 +28,8 @@ + #include <openssl/evp.h> + #include <openssl/opensslv.h> + +-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || \ ++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) + #include <stdlib.h> /* malloc, free */ + #include <string.h> /* memset */ + static inline EVP_MD_CTX *EVP_MD_CTX_new(void) diff --git a/tools/coreutils/Makefile b/tools/coreutils/Makefile new file mode 100644 index 00000000000..4109fd77b37 --- /dev/null +++ b/tools/coreutils/Makefile @@ -0,0 +1,37 @@ +# +# Copyright (C) 2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=coreutils +PKG_CPE_ID:=cpe:/a:gnu:coreutils +PKG_VERSION:=8.27 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=@GNU/coreutils +PKG_HASH:=8891d349ee87b9ff7870f52b6d9312a9db672d2439d289bc57084771ca21656b + +HOST_BUILD_PARALLEL := 1 + +BUILD_PROGRAMS = date readlink + +include $(INCLUDE_DIR)/host-build.mk + +BUILD_BINS = $(patsubst %,src/%,$(BUILD_PROGRAMS)) + +HOST_CONFIGURE_ARGS += \ + --enable-install-program=$(subst $(space),$(comma),$(strip $(BUILD_PROGRAMS))) + +HOST_MAKE_FLAGS += \ + PROGRAMS="$(BUILD_BINS)" \ + LIBRARIES= MANS= SUBDIRS=. + +define Host/Install + $(INSTALL_DIR) $(1)/bin + $(CP) $(patsubst %,$(HOST_BUILD_DIR)/%,$(BUILD_BINS)) $(1)/bin/ +endef + +$(eval $(call HostBuild)) diff --git a/tools/coreutils/patches/001-fix-macos-vasnprintf.patch b/tools/coreutils/patches/001-fix-macos-vasnprintf.patch new file mode 100644 index 00000000000..e41315d34ec --- /dev/null +++ b/tools/coreutils/patches/001-fix-macos-vasnprintf.patch @@ -0,0 +1,25 @@ +--- a/lib/vasnprintf.c ++++ b/lib/vasnprintf.c +@@ -4858,7 +4858,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t * + #endif + *fbp = dp->conversion; + #if USE_SNPRINTF +-# if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) ++# if ! (((__GLIBC__ > 2 \ ++ || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \ ++ && !defined __UCLIBC__) \ ++ || (defined __APPLE__ && defined __MACH__) \ ++ || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) + fbp[1] = '%'; + fbp[2] = 'n'; + fbp[3] = '\0'; +@@ -4872,6 +4876,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t * + in format strings in writable memory may crash the program + (if compiled with _FORTIFY_SOURCE=2), so we should avoid it + in this situation. */ ++ /* macOS 10.13 High Sierra behaves like glibc with ++ _FORTIFY_SOURCE=2, and older macOS releases ++ presumably do not need %n. */ + /* On native Windows systems (such as mingw), we can avoid using + %n because: + - Although the gl_SNPRINTF_TRUNCATION_C99 test fails, diff --git a/tools/dosfstools/Makefile b/tools/dosfstools/Makefile new file mode 100644 index 00000000000..e34ceaf32be --- /dev/null +++ b/tools/dosfstools/Makefile @@ -0,0 +1,27 @@ +# +# Copyright (C) 2012-2015 OpenWrt.org +# Copyright (C) 2016 LEDE-Project.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=dosfstools +PKG_CPE_ID:=cpe:/a:dosfstools_project:dosfstools +PKG_VERSION:=4.1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=https://github.com/dosfstools/dosfstools/releases/download/v$(PKG_VERSION)/ \ + http://fossies.org/linux/misc +PKG_HASH:=e6b2aca70ccc3fe3687365009dd94a2e18e82b688ed4e260e04b7412471cc173 + +HOST_FIXUP:=autoreconf + +include $(INCLUDE_DIR)/host-build.mk + +ifeq ($(HOST_OS),Darwin) +HOST_CFLAGS += -UHAVE_ENDIAN_H +endif + +$(eval $(call HostBuild)) diff --git a/tools/dosfstools/patches/0002-Switch-to-AC_CHECK_LIB-for-iconv-library-linking.patch b/tools/dosfstools/patches/0002-Switch-to-AC_CHECK_LIB-for-iconv-library-linking.patch new file mode 100644 index 00000000000..ea933208216 --- /dev/null +++ b/tools/dosfstools/patches/0002-Switch-to-AC_CHECK_LIB-for-iconv-library-linking.patch @@ -0,0 +1,27 @@ +From 1c6c135ee15e449c1bf2e76d5307f83a3a1d7425 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com> +Date: Tue, 11 Oct 2016 12:07:48 +0200 +Subject: [PATCH] Switch to AC_CHECK_LIB for iconv library linking. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +AC_SEARCH_LIB doesn't work properly for openwrt/lede when building dosfstools +as a package. + +Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/configure.ac ++++ b/configure.ac +@@ -59,7 +59,7 @@ if test "x$with_udev" != "xno"; then + [true]) + fi + +-AC_SEARCH_LIBS(iconv_open, iconv) ++AC_CHECK_LIB(iconv, iconv_open) + + # xxd (distributed with vim) is used in the testsuite + AC_CHECK_PROG([XXD_FOUND], [xxd], [yes]) diff --git a/tools/e2fsprogs/Makefile b/tools/e2fsprogs/Makefile index 0bfcfb4f0f1..0e12cdd9011 100644 --- a/tools/e2fsprogs/Makefile +++ b/tools/e2fsprogs/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2010 OpenWrt.org +# Copyright (C) 2010-2015 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -8,24 +8,30 @@ include $(TOPDIR)/rules.mk PKG_NAME:=e2fsprogs -PKG_VERSION:=1.41.13 -PKG_MD5SUM:=7508a192c7a9471e2128424f4eafac1c +PKG_CPE_ID:=cpe:/a:e2fsprogs_project:e2fsprogs +PKG_VERSION:=1.44.3 +PKG_HASH:=5d899f7d30f481cc0c6a049ebe26ebe145f1b524182ea1ecde4086162d4e4bb6 PKG_RELEASE:=1 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=@SF/e2fsprogs +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=@KERNEL/linux/kernel/people/tytso/e2fsprogs/v$(PKG_VERSION)/ + +HOST_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/host-build.mk -TARGET_CFLAGS += $(FPIC) +HOST_CFLAGS += $(FPIC) + +HOST_CONFIGURE_ARGS += \ + --disable-elf-shlibs \ + --enable-libuuid \ + --disable-tls \ + --disable-nls -CONFIGURE_ARGS += \ - --disable-shared \ - --enable-static \ - --disable-rpath \ - --enable-elf-shlibs \ - --enable-dynamic-e2fsck \ - --disable-tls +define Host/Prepare + $(call Host/Prepare/Default) + rm -rf $(HOST_BUILD_DIR)/doc +endef define Host/Install $(Host/Install/Default) diff --git a/tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch b/tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch index 4dbece5cef7..67a30f610b5 100644 --- a/tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch +++ b/tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch @@ -1,6 +1,6 @@ --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h -@@ -65,7 +65,7 @@ +@@ -73,7 +73,7 @@ * Exit codes used by fsck-type programs */ #define FSCK_OK 0 /* No errors */ diff --git a/tools/e2fsprogs/patches/002-dont-build-e4defrag.patch b/tools/e2fsprogs/patches/002-dont-build-e4defrag.patch new file mode 100644 index 00000000000..2a7842f6554 --- /dev/null +++ b/tools/e2fsprogs/patches/002-dont-build-e4defrag.patch @@ -0,0 +1,11 @@ +--- a/misc/Makefile.in ++++ b/misc/Makefile.in +@@ -11,7 +11,7 @@ INSTALL = @INSTALL@ + + @MCONFIG@ + +-@DEFRAG_CMT@@LINUX_CMT@E4DEFRAG_PROG= e4defrag ++@DEFRAG_CMT@@LINUX_CMT@E4DEFRAG_PROG= + @DEFRAG_CMT@@LINUX_CMT@E4DEFRAG_MAN= e4defrag.8 + + @LINUX_CMT@E4CRYPT_PROG = e4crypt diff --git a/tools/e2fsprogs/patches/002-freebsd_fix.patch b/tools/e2fsprogs/patches/002-freebsd_fix.patch deleted file mode 100644 index 5065e05d1d7..00000000000 --- a/tools/e2fsprogs/patches/002-freebsd_fix.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/lib/ext2fs/tdb.c -+++ b/lib/ext2fs/tdb.c -@@ -29,6 +29,7 @@ Last Changed Date: 2007-06-22 13:36:10 - - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -+#include <sys/file.h> - #ifdef CONFIG_STAND_ALONE - #define HAVE_MMAP - #define HAVE_STRDUP -@@ -55,7 +56,6 @@ Last Changed Date: 2007-06-22 13:36:10 - - #include <utime.h> - #endif - #include <sys/stat.h> --#include <sys/file.h> - #include <fcntl.h> - - #ifdef HAVE_SYS_MMAN_H diff --git a/tools/e2fsprogs/patches/003-darwin_directio_fix.patch b/tools/e2fsprogs/patches/003-darwin_directio_fix.patch deleted file mode 100644 index 971c7ad99b4..00000000000 --- a/tools/e2fsprogs/patches/003-darwin_directio_fix.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- a/lib/ext2fs/unix_io.c -+++ b/lib/ext2fs/unix_io.c -@@ -428,6 +428,7 @@ static errcode_t unix_open(const char *n - struct unix_private_data *data = NULL; - errcode_t retval; - int open_flags; -+ int f_nocache = 0; - struct stat st; - #ifdef __linux__ - struct utsname ut; -@@ -464,7 +465,11 @@ static errcode_t unix_open(const char *n - if (flags & IO_FLAG_EXCLUSIVE) - open_flags |= O_EXCL; - if (flags & IO_FLAG_DIRECT_IO) -+#if !defined(O_DIRECT) && defined(F_NOCACHE) -+ f_nocache = F_NOCACHE; -+#else - open_flags |= O_DIRECT; -+#endif - data->flags = flags; - - #ifdef HAVE_OPEN64 -@@ -477,6 +482,13 @@ static errcode_t unix_open(const char *n - goto cleanup; - } - -+ if (f_nocache) { -+ if (fcntl(data->dev, f_nocache, 1) < 0) { -+ retval = errno; -+ goto cleanup; -+ } -+ } -+ - #ifdef BLKSSZGET - if (flags & IO_FLAG_DIRECT_IO) { - if (ioctl(data->dev, BLKSSZGET, &data->align) != 0) diff --git a/tools/e2fsprogs/patches/003-openbsd-compat.patch b/tools/e2fsprogs/patches/003-openbsd-compat.patch new file mode 100644 index 00000000000..492b8a88608 --- /dev/null +++ b/tools/e2fsprogs/patches/003-openbsd-compat.patch @@ -0,0 +1,12 @@ +--- a/lib/blkid/getsize.c ++++ b/lib/blkid/getsize.c +@@ -29,6 +29,9 @@ + #include <fcntl.h> + #ifdef HAVE_SYS_IOCTL_H + #include <sys/ioctl.h> ++#ifdef __OpenBSD__ ++#include <sys/dkio.h> ++#endif + #endif + #ifdef HAVE_LINUX_FD_H + #include <linux/fd.h> diff --git a/tools/e2fsprogs/patches/004-big_endian_compile_fix.patch b/tools/e2fsprogs/patches/004-big_endian_compile_fix.patch deleted file mode 100644 index 9c3e3360e78..00000000000 --- a/tools/e2fsprogs/patches/004-big_endian_compile_fix.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Theodore Ts'o <tytso@mit.edu> -Date: Fri, 17 Dec 2010 03:11:43 +0000 (-0500) -Subject: libext2fs: Fix compile bug on big-endian architectures -X-Git-Url: http://git.kernel.org/?p=fs%2Fext2%2Fe2fsprogs.git;a=commitdiff_plain;h=9098c986b64bb65a2b7fcd2724a400ba1f451f6b - -libext2fs: Fix compile bug on big-endian architectures - -Addresses-Sourceforge-Bug: #3138115 - -Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> ---- - -diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c -index 6f6cec2..12427e0 100644 ---- a/lib/ext2fs/swapfs.c -+++ b/lib/ext2fs/swapfs.c -@@ -72,7 +72,7 @@ void ext2fs_swap_super(struct ext2_super_block * sb) - sb->s_flags = ext2fs_swab32(sb->s_flags); - sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written); - sb->s_snapshot_inum = ext2fs_swab32(sb->s_snapshot_inum); -- sb->s_snapshot_id = ext2fs_swab32(s_snapshot_id); -+ sb->s_snapshot_id = ext2fs_swab32(sb->s_snapshot_id); - sb->s_snapshot_r_blocks_count = - ext2fs_swab64(sb->s_snapshot_r_blocks_count); - sb->s_snapshot_list = ext2fs_swab32(sb->s_snapshot_list); - diff --git a/tools/e2fsprogs/patches/004-darwin-compat.patch b/tools/e2fsprogs/patches/004-darwin-compat.patch new file mode 100644 index 00000000000..d84aa121ca5 --- /dev/null +++ b/tools/e2fsprogs/patches/004-darwin-compat.patch @@ -0,0 +1,22 @@ +--- a/lib/blkid/blkid_types.h.in ++++ b/lib/blkid/blkid_types.h.in +@@ -9,6 +9,8 @@ + + @ASM_TYPES_HEADER@ + ++#include <stdint.h> ++ + #ifndef HAVE___U8 + #define HAVE___U8 + #ifdef __U8_TYPEDEF +--- a/lib/ext2fs/ext2_types.h.in ++++ b/lib/ext2fs/ext2_types.h.in +@@ -9,6 +9,8 @@ + + @ASM_TYPES_HEADER@ + ++#include <stdint.h> ++ + #ifndef HAVE___U8 + #define HAVE___U8 + #ifdef __U8_TYPEDEF diff --git a/tools/elftosb/Makefile b/tools/elftosb/Makefile new file mode 100644 index 00000000000..9079ac5803d --- /dev/null +++ b/tools/elftosb/Makefile @@ -0,0 +1,26 @@ +# +# Copyright (C) 2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=elftosb +PKG_VERSION:=10.12.01 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://repository.timesys.com/buildsources/e/elftosb/elftosb-10.12.01/ +PKG_HASH:=77bb6981620f7575b87d136d94c7daa88dd09195959cc75fc18b138369ecd42b + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Compile + $(MAKE) -C $(HOST_BUILD_DIR) LDFLAGS="$(HOST_LDFLAGS)" +endef + +define Host/Install + $(INSTALL_BIN) $(HOST_BUILD_DIR)/bld/linux/elftosb $(STAGING_DIR_HOST)/bin/elftosb +endef + +$(eval $(call HostBuild)) diff --git a/tools/elftosb/patches/001-libm.patch b/tools/elftosb/patches/001-libm.patch new file mode 100644 index 00000000000..02705d24bb7 --- /dev/null +++ b/tools/elftosb/patches/001-libm.patch @@ -0,0 +1,11 @@ +--- elftosb-10.12.01/makefile.rules 2012-03-15 11:01:44.979020178 -0400 ++++ elftosb-10.12.01/makefile.rules 2012-03-15 11:01:16.332761989 -0400 +@@ -101,7 +101,7 @@ + keygen.o + + +-LIBS = -lstdc++ ++LIBS = -lstdc++ -lm + + + ifeq ("${UNAMES}", "Linux") diff --git a/tools/elftosb/patches/002-fix-header-path.patch b/tools/elftosb/patches/002-fix-header-path.patch new file mode 100644 index 00000000000..5e3b5091b90 --- /dev/null +++ b/tools/elftosb/patches/002-fix-header-path.patch @@ -0,0 +1,19 @@ +This package had an absolute path for sys/types.h, which doesn't +make much sense. It breaks on newer Ubuntu systems, and probably many +others once multiarch becomes more common. + +This patch makes the types a relative path, and allows the system +to use whatever include paths it feels are correct. + +diff -Naurp elftosb-10.12.01-orig/common/stdafx.h elftosb-10.12.01/common/stdafx.h +--- elftosb-10.12.01-orig/common/stdafx.h 2012-07-12 13:30:10.990249396 -0400 ++++ elftosb-10.12.01/common/stdafx.h 2012-07-12 13:30:06.858249391 -0400 +@@ -27,7 +27,7 @@ + // For Linux systems only, types.h only defines the signed + // integer types. This is not professional code. + // Update: They are defined in the header files in the more recent version of redhat enterprise gcc. +-#include "/usr/include/sys/types.h" ++#include <sys/types.h> + #include <stdint.h> + //typedef unsigned long uint32_t; + //typedef unsigned short uint16_t; diff --git a/tools/elftosb/patches/003-use-ldflags.patch b/tools/elftosb/patches/003-use-ldflags.patch new file mode 100644 index 00000000000..82fd1e8d0ae --- /dev/null +++ b/tools/elftosb/patches/003-use-ldflags.patch @@ -0,0 +1,26 @@ +--- a/makefile.rules ++++ b/makefile.rules +@@ -131,19 +131,20 @@ exec_always: + @echo "LIBS = ${LIBS}" + @echo "EXEC_FILE = ${EXEC_FILE}" + @echo "BUILD_DIR = ${BUILD_DIR}" ++ @echo "LDFLAGS = ${LDFLAGS}" + + clean: + rm -f ${OBJ_FILES_ELFTOSB2} ${OBJ_FILES_SBTOOL} ${OBJ_FILES_KEYGEN} \ + ${EXEC_FILE_ELFTOSB2} ${EXEC_FILE_SBTOOL} ${EXEC_FILE_KEYGEN} + + elftosb: ${OBJ_FILES_ELFTOSB2} +- gcc ${OBJ_FILES_ELFTOSB2} ${LIBS} -o ${EXEC_FILE_ELFTOSB2} ++ gcc ${OBJ_FILES_ELFTOSB2} ${LIBS} ${LDFLAGS} -o ${EXEC_FILE_ELFTOSB2} + + sbtool: ${OBJ_FILES_SBTOOL} +- gcc ${OBJ_FILES_SBTOOL} ${LIBS} -o ${EXEC_FILE_SBTOOL} ++ gcc ${OBJ_FILES_SBTOOL} ${LIBS} ${LDFLAGS} -o ${EXEC_FILE_SBTOOL} + + keygen: ${OBJ_FILES_KEYGEN} +- gcc ${OBJ_FILES_KEYGEN} ${LIBS} -o ${EXEC_FILE_KEYGEN} ++ gcc ${OBJ_FILES_KEYGEN} ${LIBS} ${LDFLAGS} -o ${EXEC_FILE_KEYGEN} + + + #ifeq ("${UNAMES}", "Linux") diff --git a/tools/expat/Makefile b/tools/expat/Makefile new file mode 100644 index 00000000000..fab04e011fa --- /dev/null +++ b/tools/expat/Makefile @@ -0,0 +1,26 @@ +# +# Copyright (C) 2006-2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=expat +PKG_CPE_ID:=cpe:/a:libexpat:expat +PKG_VERSION:=2.2.5 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_HASH:=d9dc32efba7e74f788fcc4f212a43216fc37cf5f23f4c2339664d473353aedf6 +PKG_SOURCE_URL:=@SF/expat + +HOST_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Install + $(MAKE) -C $(HOST_BUILD_DIR) install +endef + +$(eval $(call HostBuild)) diff --git a/tools/findutils/Makefile b/tools/findutils/Makefile new file mode 100644 index 00000000000..c1c45eeaabd --- /dev/null +++ b/tools/findutils/Makefile @@ -0,0 +1,21 @@ +# +# Copyright (C) 2006-2016 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=findutils +PKG_CPE_ID:=cpe:/a:gnu:findutils +PKG_VERSION:=4.6.0 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@GNU/$(PKG_NAME) +PKG_HASH:=ded4c9f73731cd48fec3b6bdaccce896473b6d8e337e9612e16cf1431bb1169d + +HOST_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/host-build.mk + +$(eval $(call HostBuild)) diff --git a/tools/findutils/patches/100-include_sysmacros.patch b/tools/findutils/patches/100-include_sysmacros.patch new file mode 100644 index 00000000000..82b1ee9a42b --- /dev/null +++ b/tools/findutils/patches/100-include_sysmacros.patch @@ -0,0 +1,13 @@ +--- a/gl/lib/mountlist.c ++++ b/gl/lib/mountlist.c +@@ -17,6 +17,10 @@ + + #include <config.h> + ++#ifdef MAJOR_IN_SYSMACROS ++# include <sys/sysmacros.h> ++#endif ++ + #include "mountlist.h" + + #include <limits.h> diff --git a/tools/findutils/patches/110-glibc-change-work-around.patch b/tools/findutils/patches/110-glibc-change-work-around.patch new file mode 100644 index 00000000000..91b69274c8e --- /dev/null +++ b/tools/findutils/patches/110-glibc-change-work-around.patch @@ -0,0 +1,104 @@ +Subject: Workaround change in glibc + +Temporary workaround to compile with glibc 2.28, which +deprecated some constants + +Based on the workaround made for the tools/m4 package + +--- a/gl/lib/stdio-impl.h ++++ b/gl/lib/stdio-impl.h +@@ -18,6 +18,12 @@ + the same implementation of stdio extension API, except that some fields + have different naming conventions, or their access requires some casts. */ + ++/* Glibc 2.28 made _IO_IN_BACKUP private. For now, work around this ++ problem by defining it ourselves. FIXME: Do not rely on glibc ++ internals. */ ++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN ++# define _IO_IN_BACKUP 0x100 ++#endif + + /* BSD stdio derived implementations. */ + +--- a/gl/lib/freadahead.c ++++ b/gl/lib/freadahead.c +@@ -25,7 +25,7 @@ + size_t + freadahead (FILE *fp) + { +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + if (fp->_IO_write_ptr > fp->_IO_write_base) + return 0; + return (fp->_IO_read_end - fp->_IO_read_ptr) +--- a/gl/lib/fseeko.c ++++ b/gl/lib/fseeko.c +@@ -47,7 +47,7 @@ fseeko (FILE *fp, off_t offset, int when + #endif + + /* These tests are based on fpurge.c. */ +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + if (fp->_IO_read_end == fp->_IO_read_ptr + && fp->_IO_write_ptr == fp->_IO_write_base + && fp->_IO_save_base == NULL) +@@ -123,7 +123,7 @@ fseeko (FILE *fp, off_t offset, int when + return -1; + } + +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + fp->_flags &= ~_IO_EOF_SEEN; + fp->_offset = pos; + #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ +--- a/gl/lib/fflush.c ++++ b/gl/lib/fflush.c +@@ -33,7 +33,7 @@ + #undef fflush + + +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + + /* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */ + static void +@@ -72,7 +72,7 @@ clear_ungetc_buffer (FILE *fp) + + #endif + +-#if ! (defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */) ++#if ! (defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */) + + # if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */ +@@ -148,7 +148,7 @@ rpl_fflush (FILE *stream) + if (stream == NULL || ! freading (stream)) + return fflush (stream); + +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + + clear_ungetc_buffer_preserving_position (stream); + +--- a/gl/lib/freading.c ++++ b/gl/lib/freading.c +@@ -31,7 +31,7 @@ freading (FILE *fp) + /* Most systems provide FILE as a struct and the necessary bitmask in + <stdio.h>, because they need it for implementing getc() and putc() as + fast macros. */ +-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + return ((fp->_flags & _IO_NO_WRITES) != 0 + || ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0 + && fp->_IO_read_base != NULL)); +--- a/gl/lib/fpurge.c ++++ b/gl/lib/fpurge.c +@@ -62,7 +62,7 @@ fpurge (FILE *fp) + /* Most systems provide FILE as a struct and the necessary bitmask in + <stdio.h>, because they need it for implementing getc() and putc() as + fast macros. */ +-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + fp->_IO_read_end = fp->_IO_read_ptr; + fp->_IO_write_ptr = fp->_IO_write_base; + /* Avoid memory leak when there is an active ungetc buffer. */ diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile index 43642235465..436a43794cd 100644 --- a/tools/firmware-utils/Makefile +++ b/tools/firmware-utils/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006-2011 OpenWrt.org +# Copyright (C) 2006-2012 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -12,51 +12,79 @@ include $(INCLUDE_DIR)/host-build.mk include $(INCLUDE_DIR)/kernel.mk define cc - $(HOSTCC) $(HOST_CFLAGS) -include endian.h -o $(HOST_BUILD_DIR)/bin/$(firstword $(1)) $(foreach src,$(1),src/$(src).c) $(2) + $(HOSTCC) $(HOST_CFLAGS) -include endian.h $(HOST_LDFLAGS) -o $(HOST_BUILD_DIR)/bin/$(firstword $(1)) $(foreach src,$(1),src/$(src).c) $(2) endef define Host/Compile mkdir -p $(HOST_BUILD_DIR)/bin $(call cc,addpattern) + $(call cc,asustrx) $(call cc,trx) + $(call cc,otrx) $(call cc,motorola-bin) $(call cc,dgfirmware) + $(call cc,mksenaofw md5) $(call cc,trx2usr) $(call cc,ptgen) - $(call cc,airlink) $(call cc,srec2bin) $(call cc,mkmylofw) $(call cc,mkcsysimg) $(call cc,mkzynfw) $(call cc,lzma2eva,-lz) $(call cc,mkcasfw) - $(call cc,mkfwimage,-lz) + $(call cc,mkfwimage,-lz -Wall) $(call cc,mkfwimage2,-lz) - $(call cc,imagetag imagetag_cmdline) + $(call cc,imagetag imagetag_cmdline cyg_crc32) $(call cc,add_header) $(call cc,makeamitbin) $(call cc,encode_crc) $(call cc,nand_ecc) $(call cc,mkplanexfw sha1) - $(call cc,mktplinkfw md5) + $(call cc,mktplinkfw mktplinkfw-lib md5, -Wall -fgnu89-inline) + $(call cc,mktplinkfw2 mktplinkfw-lib md5, -fgnu89-inline) + $(call cc,tplink-safeloader md5, -Wall --std=gnu99) $(call cc,pc1crypt) $(call cc,osbridge-crc) $(call cc,wrt400n cyg_crc32) - $(call cc,wndr3700) $(call cc,mkdniimg) $(call cc,mktitanimg) $(call cc,mkchkimg) $(call cc,mkzcfw cyg_crc32) $(call cc,spw303v) + $(call cc,zyxbcm) $(call cc,trx2edips) $(call cc,xorimage) $(call cc,buffalo-enc buffalo-lib, -Wall) $(call cc,buffalo-tag buffalo-lib, -Wall) $(call cc,buffalo-tftp buffalo-lib, -Wall) $(call cc,mkwrgimg md5, -Wall) + $(call cc,mkwrggimg md5, -Wall) $(call cc,mkedimaximg) $(call cc,mkbrncmdline) $(call cc,mkbrnimg) + $(call cc,mkdapimg) + $(call cc,mkdapimg2) + $(call cc, mkcameofw, -Wall) + $(call cc,seama md5) + $(call cc,oseama md5, -Wall) + $(call cc,fix-u-media-header cyg_crc32,-Wall) + $(call cc,hcsmakeimage bcmalgo) + $(call cc,mkporayfw, -Wall) + $(call cc,mkhilinkfw, -lcrypto) + $(call cc,mkdcs932, -Wall) + $(call cc,mkheader_gemtek,-lz) + $(call cc,mkrtn56uimg, -lz) + $(call cc,dgn3500sum, -Wall) + $(call cc,edimax_fw_header, -Wall) + $(call cc,mkmerakifw sha1, -Wall) + $(call cc,mkmerakifw-old, -Wall) + $(call cc,jcgimage, -lz -Wall) + $(call cc,mkbuffaloimg, -Wall) + $(call cc,zyimage, -Wall) + $(call cc,mkdhpimg buffalo-lib, -Wall) + $(call cc,mkdlinkfw mkdlinkfw-lib, -lz -Wall --std=gnu99) + $(call cc,dns313-header, -Wall) + $(call cc,mksercommfw, -Wall --std=gnu99) endef define Host/Install diff --git a/tools/firmware-utils/src/addpattern.c b/tools/firmware-utils/src/addpattern.c index da6797c9ced..9bc48653356 100644 --- a/tools/firmware-utils/src/addpattern.c +++ b/tools/firmware-utils/src/addpattern.c @@ -58,6 +58,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <errno.h> #include <time.h> #include <unistd.h> #include <sys/stat.h> @@ -77,10 +78,11 @@ /* (from 3.00.24 firmware cyutils.h) */ #define SUPPORT_4704_CHIP 0x0008 #define SUPPORT_5352E_CHIP 0x0010 +/* (from WD My Net Wi-Fi Range Extender's cyutils.s) */ +#define SUPPORT_4703_CHIP 0x0020 struct code_header { /* from cyutils.h */ - char magic[4]; - char res1[4]; /* for extra magic */ + char magic[8]; char fwdate[3]; char fwvern[3]; char id[4]; /* U2ND */ @@ -105,11 +107,25 @@ struct board_info { struct board_info boards[] = { { + .id = "E2100L", + .pattern = "NL1X", + .hw_ver = 0x00, + .sn = 0x0f, + .flags = {0x3f, 0x00}, + }, + { .id = "WRT160NL", .pattern = "NL16", .hw_ver = 0x00, .sn = 0x0f, .flags = {0x3f, 0x00}, + }, + { + .id = "mynet-rext", + .pattern = "WDHNSTFH", + .hw_ver = 0x00, + .sn = 0x00, + .flags = {0x3f, 0x00}, }, { /* Terminating entry */ .id = NULL, @@ -126,6 +142,20 @@ void usage(void) exit(EXIT_FAILURE); } +static time_t source_date_epoch = -1; +static void set_source_date_epoch() { + char *env = getenv("SOURCE_DATE_EPOCH"); + char *endptr = env; + errno = 0; + if (env && *env) { + source_date_epoch = strtoull(env, &endptr, 10); + if (errno || (endptr && *endptr != '\0')) { + fprintf(stderr, "Invalid SOURCE_DATE_EPOCH"); + exit(1); + } + } +} + struct board_info *find_board(char *id) { struct board_info *board; @@ -243,8 +273,8 @@ int main(int argc, char **argv) hdr->flags[1] = board->flags[1]; } - if (strlen(pattern) != 4) { - fprintf(stderr, "illegal pattern \"%s\": length != 4\n", pattern); + if (strlen(pattern) > 8) { + fprintf(stderr, "illegal pattern \"%s\"\n", pattern); usage(); } @@ -258,7 +288,10 @@ int main(int argc, char **argv) usage(); } - if (time(&t) == (time_t)(-1)) { + set_source_date_epoch(); + if (source_date_epoch != -1) { + t = source_date_epoch; + } else if ((time(&t) == (time_t)(-1))) { fprintf(stderr, "time call failed\n"); return EXIT_FAILURE; } @@ -270,16 +303,16 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - memcpy(&hdr->magic, pattern, 4); + memcpy(hdr->magic, pattern, strlen(pattern)); if (pbotflag) - memcpy(&hdr->res1, pbotpat, 4); + memcpy(&hdr->magic[4], pbotpat, 4); hdr->fwdate[0] = ptm->tm_year % 100; hdr->fwdate[1] = ptm->tm_mon + 1; hdr->fwdate[2] = ptm->tm_mday; hdr->fwvern[0] = v0; hdr->fwvern[1] = v1; hdr->fwvern[2] = v2; - memcpy(&hdr->id, CODE_ID, strlen(CODE_ID)); + memcpy(hdr->id, CODE_ID, strlen(CODE_ID)); off = sizeof(struct code_header); diff --git a/tools/firmware-utils/src/airlink.c b/tools/firmware-utils/src/airlink.c deleted file mode 100644 index 560a58df59e..00000000000 --- a/tools/firmware-utils/src/airlink.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Thanks to Vassily Galinsky for this tool -***************************************************************************** -AIRLINK AR525W firmware image structure - -8:-5 Extended (httpd) header checksum - sum2 - -4:-1 Extended (httpd) header magic - "ARRN" - 0x4e525241 - 0: 3 Standard (tftpd) header magic - "GMTK" - 0x4b544d47 - 4: 7 Standard (tftpd) header checksum - sum1 - 8: b 0 - c: f Size of compressed linux kernel - 10:13 Size of firmware image file with standard header - 14:17 Product code - 0x5 - 18:1b Bootloader checksum - sum0 - 1c:1f 0 - 20: Compressed linux kernel - - Squashfs or jffs2 file system - kernel dependent - either 32 bytes or sector aligned -*****************************************************************************/ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <netinet/in.h> - -typedef unsigned char uchar; - -uint32_t crctab[257] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, - 0 -}; - -uint32_t header[] = { - 0x00000000, 0x4e525241, - 0x4b544d47, 0x00000000, 0x00000000, 0x000afd4a, - 0x00000000, 0x00000005, 0x00000000, 0x00000000 -}; - -static int JFFS2 = 0; - -int generate_image(char *kname, char *fsname, char *fname, int EHDR) -{ - int i; - uint32_t lenk, lens; - uchar *bk, *bs; - int fkd, ffd, fsd; - fkd = open(kname, O_RDONLY); - ffd = creat(fname, 0644); - if ((fkd < 0) || (ffd < 0)) - return -1; - if (fsname) { - fsd = open(fsname, O_RDONLY); - if (fsd < 0) - return -1; - } - lenk = lseek(fkd, 0, SEEK_END); - header[5] = lenk; - bk = (uchar *) mmap(NULL, lenk, PROT_READ, MAP_SHARED, fkd, 0); - if (bk == MAP_FAILED) - return -1; - if (fsname) { - lens = lseek(fsd, 0, SEEK_END); - bs = (uchar *) mmap(NULL, lens, PROT_READ, MAP_SHARED, fsd, - 0); - if (bs == MAP_FAILED) - return -1; - } - if (EHDR) - write(ffd, header, 0x28); - else - write(ffd, header + 2, 0x20); - write(ffd, bk, lenk); - lenk += 0x20; - if (!JFFS2) JFFS2 = 0x20; - printf("Padding header+kernel - 0x%x + 0x%x = 0x%x\n", - lenk, ((lenk - 1 + JFFS2) / JFFS2) * JFFS2 - lenk, - ((lenk - 1 + JFFS2) / JFFS2) * JFFS2); - for (i = 0; i < ((lenk - 1 + JFFS2) / JFFS2) * JFFS2 - lenk; i++) - write(ffd, header, 1); - if (fsname) { - write(ffd, bs, lens); - close(fsd); - } - close(ffd); - close(fkd); - return 0; -} - -uint32_t crc32(uchar * buf, uint32_t len) -{ - register int i; - uint32_t sum; - register uint32_t s0; - s0 = ~0; - for (i = 0; i < len; i++) { - s0 = (s0 >> 8) ^ crctab[(uchar) (s0 & 0xFF) ^ buf[i]]; - } - sum = ~s0; - return sum; -} - -void usage(char *prog) -{ - printf("Usage: %s [-b 0/1] image_filename \n", prog); - printf(" update checksums for firmware file\n"); - printf - ("Usage: %s [-b 0/1] [-j erasesize_in_kibytes] [-e] kernel filesystem image_filename \n", - prog); - printf(" generate firmware file and update checksums\n"); - printf("--------------------------------------------------\n"); - printf(" -e - generate header for web upload\n"); - printf(" -b 0/1 - clear/update bootloader checksum\n"); - printf(" -j erasesize_in_kibytes - generate header for jffs2 filesystem\n"); -} - -int main(int argc, char **argv) -{ - uchar b[0x400]; - char EHDR = 0; - char BHDR = 0; - int c, fd; - extern char *optarg; - extern int optind, optopt; - - while ((c = getopt(argc, argv, "b:ej:")) != -1) { - switch (c) { - case 'b': - if (optarg[0] == '1') - BHDR = 1; - break; - case 'e': - EHDR = 1; - break; - case 'j': - sscanf(optarg, "%i", &JFFS2); - JFFS2 *= 1024; - break; - case '?': - fprintf(stderr, "\nError: unknown arg %c\n\n\n", - optopt); - usage(argv[0]); - exit(-1); - } - } - if (((argc - optind) < 1) && ((argc - optind) > 3)) { - usage(argv[0]); - exit(-1); - } - if ((argc - optind) == 3) - if (generate_image - (argv[optind], argv[optind + 1], argv[optind + 2], - EHDR)) { - fprintf(stderr, - "\nError generating image file %s\n\n\n", - argv[argc - 1]); - usage(argv[0]); - exit(-1); - } - if ((argc - optind) == 2) - if (generate_image - (argv[optind], NULL, argv[optind + 1], EHDR)) { - fprintf(stderr, - "\nError generating image file %s\n\n\n", - argv[argc - 1]); - usage(argv[0]); - exit(-1); - } - - fd = open(argv[argc - 1], O_RDWR); - if (fd < 0) { - fprintf(stderr, "\nImage file not found %s\n\n\n", - argv[argc - 1]); - usage(argv[0]); - exit(-1); - } - long i, len = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); - uchar *buf = malloc(len); - read(fd, buf, len); - uint32_t sum, l0; - uint32_t MagicS = 0x474d544b; - uint32_t MagicE = 0x4152524e; - if (ntohl(*((uint32_t *) buf)) == MagicS) { - fprintf(stderr, - "Image without extra 8 bytes - Standard header\n"); - buf[0x10] = len & 0xff; - buf[0x11] = (len >> 8) & 0xff; - buf[0x12] = (len >> 16) & 0xff; - buf[0x13] = (len >> 24) & 0xff; - lseek(fd, 0x10, SEEK_SET); - write(fd, buf + 0x10, 0x4); - EHDR = 0; - } else if ((ntohl(*((uint32_t *) (buf + 0x8))) == MagicS) - && ((ntohl(*((uint32_t *) (buf + 0x4))) == MagicE))) { - fprintf(stderr, - "Image with extra 8 bytes - Extended header\n"); - *((uint32_t *) (buf + 0x18)) = len - 8; - buf[0x18] = (len - 8) & 0xff; - buf[0x19] = ((len - 8) >> 8) & 0xff; - buf[0x1a] = ((len - 8) >> 16) & 0xff; - buf[0x1b] = ((len - 8) >> 24) & 0xff; - lseek(fd, 0x18, SEEK_SET); - write(fd, buf + 0x18, 0x4); - buf += 8; - EHDR = 1; - } else if (len == buf[0x10] | ((uint32_t)buf[0x11] << 8) | ((uint32_t)buf[0x12] << 16) | ((uint32_t)buf[0x13] << 24)) { - fprintf(stderr, - "Image without extra 8 bytes - Standard header\n"); - EHDR = 0; - } else if (len == (buf[0x18] | ((uint32_t)buf[0x19] << 8) | ((uint32_t)buf[0x1a] << 16) | ((uint32_t)buf[0x1b] << 24)) + 8) { - fprintf(stderr, - "Image with extra 8 bytes - Extended header\n"); - buf += 8; - EHDR = 1; - } else { - fprintf(stderr, "ERROR: Wrong image size\n"); - exit(-1); - } - l0 = buf[0x10] | ((uint32_t)buf[0x11] << 8) | ((uint32_t)buf[0x12] << 16) | ((uint32_t)buf[0x13] << 24); - if (!BHDR) - *((uint32_t *) & buf[0x18]) = 0; - unsigned long sum0 = buf[0x18] | ((uint32_t)buf[0x19] << 8) | ((uint32_t)buf[0x1a] << 16) | ((uint32_t)buf[0x1b] << 24); - unsigned long sum1 = buf[0x4] | ((uint32_t)buf[0x5] << 8) | ((uint32_t)buf[0x6] << 16) | ((uint32_t)buf[0x7] << 24); - *((uint32_t *) & buf[0x4]) = 0x0L; - memcpy(b, buf, 0x100); - memcpy(b + 0x100, buf + ((l0 >> 1) - ((l0 & 0x6) >> 1)), 0x100); - memcpy(b + 0x200, buf + (l0 - 0x200), 0x200); - *((uint32_t *) & b[0x18]) = 0x0L; - - sum = crc32(b, 0x400); - printf("CRC32 sum0 - (%x, %x, %x)\n", sum, sum0, 0x400); - if (EHDR) - lseek(fd, 0x20, SEEK_SET); - else - lseek(fd, 0x18, SEEK_SET); - buf[0x18] = (BHDR ? sum : sum0) & 0xff; - buf[0x19] = ((BHDR ? sum : sum0) >> 8) & 0xff; - buf[0x1a] = ((BHDR ? sum : sum0) >> 16) & 0xff; - buf[0x1b] = ((BHDR ? sum : sum0) >> 24) & 0xff; - write(fd, &buf[0x18], 0x4); - - sum = crc32(buf, l0); - printf("CRC32 sum1 - (%x, %x, %x)\n", sum, sum1, l0); - if (EHDR) - lseek(fd, 0xC, SEEK_SET); - else - lseek(fd, 0x4, SEEK_SET); - buf[0x4] = sum & 0xff; - buf[0x5] = (sum >> 8) & 0xff; - buf[0x6] = (sum >> 16) & 0xff; - buf[0x7] = (sum >> 24) & 0xff; - write(fd, &buf[0x4], 0x4); - if (EHDR) { - unsigned long sum2 = buf[-0x8] | ((uint32_t)buf[-0x7] << 8) | ((uint32_t)buf[-0x6] << 16) | ((uint32_t)buf[-0x5] << 24); - *((uint32_t *) & buf[-0x8]) = 0L; - sum = crc32(buf - 0x4, len - 0x4); - printf("CRC32 sum2 - (%x, %x, %x)\n", sum, sum2, - len - 0x4); - lseek(fd, 0, SEEK_SET); - *((uint32_t *) & buf[-0x8]) = htonl(sum); - write(fd, &buf[-0x8], 0x4); - buf -= 8; - } - close(fd); - free(buf); - return 0; -} diff --git a/tools/firmware-utils/src/asustrx.c b/tools/firmware-utils/src/asustrx.c new file mode 100644 index 00000000000..67f2680b31b --- /dev/null +++ b/tools/firmware-utils/src/asustrx.c @@ -0,0 +1,256 @@ +/* + * asustrx + * + * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include <byteswap.h> +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_le32(x) bswap_32(x) +#define le32_to_cpu(x) bswap_32(x) +#elif __BYTE_ORDER == __LITTLE_ENDIAN +#define cpu_to_le32(x) (x) +#define le32_to_cpu(x) (x) +#else +#error "Unsupported endianness" +#endif + +#define TRX_MAGIC 0x30524448 +#define TRX_FLAGS_OFFSET 12 + +struct trx_header { + uint32_t magic; + uint32_t length; + uint32_t crc32; + uint16_t flags; + uint16_t version; + uint32_t offset[3]; +}; + +struct asustrx_tail { + uint8_t version[4]; + char productid[12]; + uint8_t unused[48]; +}; + +char *in_path = NULL; +char *out_path = NULL; +char *productid = NULL; +uint8_t version[4] = { }; + +static const uint32_t crc32_tbl[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +static void parse_options(int argc, char **argv) { + int c; + + while ((c = getopt(argc, argv, "i:o:p:v:")) != -1) { + switch (c) { + case 'i': + in_path = optarg; + break; + case 'o': + out_path = optarg; + break; + case 'p': + productid = optarg; + break; + case 'v': + if (sscanf(optarg, "%hu.%hu.%hu.%hu", &version[0], &version[1], &version[2], &version[3]) != 4) + fprintf(stderr, "Version %s doesn't match suppored 4-digits format\n", optarg); + break; + } + } +} + +static void usage() { + printf("Usage:\n"); + printf("\t-i file\t\t\t\tinput TRX file\n"); + printf("\t-o file\t\t\t\toutput Asus TRX file\n"); + printf("\t-p productid\t\t\tproduct (device) ID\n"); + printf("\t-v version\t\t\tfirmware version formatted with 4 digits like: 1.2.3.4\n"); +} + +int main(int argc, char **argv) { + struct trx_header hdr; + struct asustrx_tail tail = { }; + FILE *in, *out; + uint8_t buf[1024]; + size_t bytes; + size_t length = 0; + uint32_t crc32 = 0xffffffff; + int i; + int err = 0; + + /* Parse & validate arguments */ + parse_options(argc, argv); + if (!in_path || !out_path || !productid) { + usage(); + err = -EINVAL; + goto err; + } + + /* Fill Asus tail */ + tail.version[0] = version[0]; + tail.version[1] = version[1]; + tail.version[2] = version[2]; + tail.version[3] = version[3]; + strncpy(tail.productid, productid, sizeof(tail.productid)); + + /* Open files */ + in = fopen(in_path, "r"); + if (!in) { + fprintf(stderr, "Couldn't open %s\n", in_path); + err = -EIO; + goto err; + } + out = fopen(out_path, "w+"); + if (!out) { + fprintf(stderr, "Couldn't open %s\n", out_path); + err = -EIO; + goto err; + } + + /* Check is there is empty place for Asus tail */ + bytes = sizeof(struct asustrx_tail); + fseek(in, -bytes, SEEK_END); + if (fread(buf, 1, bytes, in) != bytes) { + fprintf(stderr, "Couldn't read %zu B from %s\n", bytes, in_path); + err = -EIO; + goto err; + } + for (i = 0; i < bytes; i++) { + if (buf[i]) { + fprintf(stderr, "Input TRX doesn't have last 64 B empty %s\n", out_path); + err = -ENOSPC; + goto err; + } + } + + /* Copy whole TRX */ + rewind(in); + while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) { + if (fwrite(buf, 1, bytes, out) != bytes) { + fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path); + err = -EIO; + goto err; + } + } + + /* Overwrite last 64 B with Asus tail */ + bytes = sizeof(tail); + fseek(out, -bytes, SEEK_CUR); + if (fwrite(&tail, 1, bytes, out) != bytes) { + fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path); + err = -EIO; + goto err; + } + + /* Calculate crc32 */ + fseek(out, TRX_FLAGS_OFFSET, SEEK_SET); + length = TRX_FLAGS_OFFSET; + while ((bytes = fread(buf, 1, sizeof(buf), out )) > 0) { + length += bytes; + for (i = 0; i < bytes; i++) + crc32 = crc32_tbl[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8); + } + + /* Update header */ + bytes = sizeof(hdr); + rewind(out); + if (fread(&hdr, 1, sizeof(hdr), out) != bytes) { + fprintf(stderr, "Couldn't read %zu B from %s\n", bytes, in_path); + err = -EIO; + goto err; + } + hdr.crc32 = cpu_to_le32(crc32); + rewind(out); + if (fwrite(&hdr, 1, bytes, out) != bytes) { + fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path); + err = -EIO; + goto err; + } + +err: + if (out) + fclose(out); + if (in) + fclose(in); + return err; +} diff --git a/tools/firmware-utils/src/bcm_tag.h b/tools/firmware-utils/src/bcm_tag.h index 2e977a2d7a6..2730edc9ad9 120000..100644 --- a/tools/firmware-utils/src/bcm_tag.h +++ b/tools/firmware-utils/src/bcm_tag.h @@ -1 +1,70 @@ -../../../target/linux/brcm63xx/files/arch/mips/include/asm/mach-bcm63xx/bcm_tag.h
\ No newline at end of file +#ifndef __BCM63XX_TAG_H +#define __BCM63XX_TAG_H + +#define TAGVER_LEN 4 /* Length of Tag Version */ +#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */ +#define SIG1_LEN 20 /* Company Signature 1 Length */ +#define SIG2_LEN 14 /* Company Signature 2 Lenght */ +#define BOARDID_LEN 16 /* Length of BoardId */ +#define ENDIANFLAG_LEN 2 /* Endian Flag Length */ +#define CHIPID_LEN 6 /* Chip Id Length */ +#define IMAGE_LEN 10 /* Length of Length Field */ +#define ADDRESS_LEN 12 /* Length of Address field */ +#define DUALFLAG_LEN 2 /* Dual Image flag Length */ +#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */ +#define RSASIG_LEN 20 /* Length of RSA Signature in tag */ +#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */ +#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */ +#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */ +#define CRC_LEN 4 /* Length of CRC in bytes */ +#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */ + +#define NUM_PIRELLI 2 +#define IMAGETAG_CRC_START 0xFFFFFFFF + +#define PIRELLI_BOARDS { \ + "AGPF-S0", \ + "DWV-S0", \ +} + +/* + * The broadcom firmware assumes the rootfs starts the image, + * therefore uses the rootfs start (flashImageAddress) + * to determine where to flash the image. Since we have the kernel first + * we have to give it the kernel address, but the crc uses the length + * associated with this address (rootLength), which is added to the kernel + * length (kernelLength) to determine the length of image to flash and thus + * needs to be rootfs + deadcode (jffs2 EOF marker) +*/ + +struct bcm_tag { + char tagVersion[TAGVER_LEN]; // 0-3: Version of the image tag + char sig_1[SIG1_LEN]; // 4-23: Company Line 1 + char sig_2[SIG2_LEN]; // 24-37: Company Line 2 + char chipid[CHIPID_LEN]; // 38-43: Chip this image is for + char boardid[BOARDID_LEN]; // 44-59: Board name + char big_endian[ENDIANFLAG_LEN]; // 60-61: Map endianness -- 1 BE 0 LE + char totalLength[IMAGE_LEN]; // 62-71: Total length of image + char cfeAddress[ADDRESS_LEN]; // 72-83: Address in memory of CFE + char cfeLength[IMAGE_LEN]; // 84-93: Size of CFE + char flashImageStart[ADDRESS_LEN]; // 94-105: Address in memory of image start (kernel for OpenWRT, rootfs for stock firmware) + char flashRootLength[IMAGE_LEN]; // 106-115: Size of rootfs for flashing + char kernelAddress[ADDRESS_LEN]; // 116-127: Address in memory of kernel + char kernelLength[IMAGE_LEN]; // 128-137: Size of kernel + char dualImage[DUALFLAG_LEN]; // 138-139: Unused at present + char inactiveFlag[INACTIVEFLAG_LEN]; // 140-141: Unused at present + char rsa_signature[RSASIG_LEN]; // 142-161: RSA Signature (unused at present; some vendors may use this) + char information1[TAGINFO1_LEN]; // 162-191: Compilation and related information (not generated/used by OpenWRT) + char flashLayoutVer[FLASHLAYOUTVER_LEN];// 192-195: Version flash layout + char fskernelCRC[CRC_LEN]; // 196-199: kernel+rootfs CRC32 + char information2[TAGINFO2_LEN]; // 200-215: Unused at present except Alice Gate where is is information + char imageCRC[CRC_LEN]; // 216-219: CRC32 of image less imagetag (kernel for Alice Gate) + char rootfsCRC[CRC_LEN]; // 220-223: CRC32 of rootfs partition + char kernelCRC[CRC_LEN]; // 224-227: CRC32 of kernel partition + char imageSequence[4]; // 228-231: Image sequence number + char rootLength[4]; // 232-235: steal from reserved1 to keep the real root length so we can use in the flash map even after we have change the rootLength to 0 to satisfy devices that check CRC on every boot + char headerCRC[CRC_LEN]; // 236-239: CRC32 of header excluding tagVersion + char reserved2[16]; // 240-255: Unused at present +}; + +#endif /* __BCM63XX_TAG_H */ diff --git a/tools/firmware-utils/src/bcmalgo.c b/tools/firmware-utils/src/bcmalgo.c new file mode 100644 index 00000000000..e7d3b113bec --- /dev/null +++ b/tools/firmware-utils/src/bcmalgo.c @@ -0,0 +1,248 @@ +#include <stdlib.h> +#include <sys/types.h> +#include <stdio.h> +#include <inttypes.h> +#include <string.h> +#include <getopt.h> +#include <unistd.h> +#include <sys/time.h> +#include <sys/stat.h> +#include "bcmalgo.h" + + +#define UTIL_VERSION "0.1" +#define ENDIAN_REVERSE_NEEDED + +uint32_t reverse_endian32 ( uint32_t data ) +{ +#ifdef ENDIAN_REVERSE_NEEDED + return 0 | ( data & 0x000000ff ) << 24 + | ( data & 0x0000ff00 ) << 8 + | ( data & 0x00ff0000 ) >> 8 + | ( data & 0xff000000 ) >> 24; +#else + return data; +#endif +} + +uint16_t reverse_endian16 ( uint16_t data ) +{ +#ifdef ENDIAN_REVERSE_NEEDED + return 0 | ( data & 0x00ff ) << 8 + | ( data & 0xff00 ) >> 8; +#else + return data; +#endif +} + + + +uint32_t get_buffer_crc ( char* filebuffer,size_t size ) +{ + + long crc=0xffffffffL; + long crcxor = 0xffffffffL; + long num4 = 0xffffffffL; + long num5 = size; + long num6 = 0x4c11db7L; + long num7 = 0x80000000L; + int i; + long j; + for ( i = 0; i < ( num5 ); i++ ) + { + long num2 = filebuffer[i]; + for ( j = 0x80L; j != 0L; j = j >> 1 ) + { + long num3 = crc & num7; + crc = crc << 1; + if ( ( num2 & j ) != 0L ) + { + num3 ^= num7; + } + if ( num3 != 0L ) + { + crc ^= num6; + } + } + } + crc ^= crcxor; + crc &= num4; + + uint8_t b1 = ( uint8_t ) ( ( crc & -16777216L ) >> 0x18 ); + uint8_t b2 = ( uint8_t ) ( ( crc & 0xff0000L ) >> 0x10 ); + uint8_t b3 = ( uint8_t ) ( ( crc & 0xff00L ) >> 8 ); + uint8_t b4 = ( uint8_t ) ( crc & 0xffL ); + int32_t crc_result = ( b1 | b2 << 8| b3 << 16| b4 <<24 ); + return reverse_endian32 ( crc_result ); +} + +//Thnx to Vector for the algo. +uint32_t get_file_crc ( char* filename ) +{ + struct stat buf; + stat ( filename,&buf ); + char* filebuffer = malloc ( buf.st_size+10 ); + FILE* fd = fopen ( filename,"r" ); + fread ( filebuffer, 1, buf.st_size,fd ); + fclose ( fd ); + uint32_t crc = get_buffer_crc ( filebuffer,buf.st_size ); + free ( filebuffer ); + return crc; +} + + + +uint16_t get_hcs ( ldr_header_t* hd ) +{ + uint8_t* head = ( uint8_t* ) hd; + uint8_t hcs_minor; + uint8_t hcs_major; + uint16_t n = 0xffff; + uint16_t m = 0; + int state = 0; + int i,j; + for ( i = 0; i < 0x54; i++ ) + { + uint16_t m = head[i]; + m = m << 8; + for ( j = 0; j < 8; j++ ) + { + if ( ( ( n ^ m ) & 0x8000 ) == 0 ) + { + state = 0; + } + else + { + state = 1; + } + n = n << 1; + if ( state ) + { + n ^= 0x1021; + } + m = m << 1; + } + n &= 0xffff; + } + n ^= 0xffff; + hcs_major = ( uint8_t ) ( ( n & 0xff00 ) >> 8 ); + hcs_minor = ( uint8_t ) ( n & 0xff ); + uint16_t hcs = hcs_major <<8 | hcs_minor; + return hcs; +} + +ldr_header_t* construct_header ( uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc_data ) +{ + ldr_header_t* hd = malloc ( sizeof ( ldr_header_t ) ); + hd->magic=reverse_endian16 ( magic ); + hd->control=0; //FixMe: Make use of it once compression is around + hd->rev_min = reverse_endian16 ( rev_min ); + hd->rev_maj = reverse_endian16 ( rev_maj ); + hd->build_date = reverse_endian32 ( build_date ); + hd->filelen = reverse_endian32 ( filelen ); + hd->ldaddress = reverse_endian32 ( ldaddress ); + printf ( "Creating header for %s...\n", filename ); + if ( strlen ( filename ) >63 ) + { + printf ( "[!] Filename too long - stripping it to 63 bytes.\n" ); + strncpy ( ( char* ) &hd->filename, filename, 63 ); + hd->filename[63]=0x00; + } + else + { + strcpy ( ( char* ) &hd->filename, filename ); + } + hd->crc=reverse_endian32 ( crc_data ); + hd->hcs = reverse_endian16 ( get_hcs ( hd ) ); + return hd; +} + +static char control_unc[] = "Uncompressed"; +static char control_lz[] = "LZRW1/KH"; +static char control_mlzo[] = "mini-LZO"; +static char control_nrv[] = "NRV2D99 [Bootloader?]"; +static char control_nstdlzma[] = "(non-standard) LZMA"; +static char control_unk[] = "Unknown"; +char* get_control_info ( uint16_t control ) +{ + control = reverse_endian16 ( control ); + switch ( control ) + { + case 0: + return control_unc; + break; + case 1: + return control_lz; + break; + case 2: + return control_mlzo; + break; + case 3: + return control_unc; + break; + case 4: + return control_nrv; + break; + case 5: + return control_nstdlzma; + break; + case 6: + return control_unc; + break; + case 7: + return control_unc; + break; + default: + return control_unk; + break; + } + +} + +int dump_header ( ldr_header_t* hd ) +{ + printf ( "=== Header Information ===\n" ); + printf ( "Header magic:\t0x%04X\n",reverse_endian16 ( hd->magic ) ); + printf ( "Control:\t0x%04X (%s)\n",reverse_endian16 ( hd->control ), get_control_info ( hd->control ) ); + printf ( "Major rev. :\t0x%04X\n",reverse_endian16 ( hd->rev_maj ) ); + printf ( "Minor rev. :\t0x%04X\n",reverse_endian16 ( hd->rev_min ) ); + printf ( "File name :\t%s\n", ( char* ) &hd->filename ); + printf ( "File length:\t%d bytes\n", reverse_endian32 ( hd->filelen ) ); + printf ( "Build time:\t0x%08X //FixMe: print in human-readable form\n", reverse_endian32 ( hd->build_date ) ); //FixMe: + printf ( "HCS:\t\t0x%04X ",reverse_endian16 ( hd->hcs ) ); + uint16_t hcs = get_hcs ( hd ); + int ret=0; + if ( hcs ==reverse_endian16 ( hd->hcs ) ) + { + printf ( "(OK!)\n" ); + } + else + { + printf ( "(ERROR! expected 0x%04X)\n",hcs ); + ret=1; + } +//printf("HCS:\t0x%02X",reverse_endian32(hd->hcs)); + printf ( "Load address:\t0x%08X\n", reverse_endian32 ( hd->ldaddress ) ); //FixMe: + printf ( "HNW:\t\t0x%04X\n",reverse_endian16 ( hd->her_znaet_chto ) ); //Hell knows what + printf ( "CRC:\t\t0x%08X\n",reverse_endian32 ( hd->crc ) ); + printf ( "=== Binary Header Dump===\n" ); + int i,j; + uint8_t* head = ( uint8_t* ) hd; + for ( i=0;i<=sizeof ( ldr_header_t );i++ ) + { + if ( i % 8==0 ) + printf ( "\n" ); + printf ( "0x%02x ",head[i] ); + } + printf ( "\n\n== End Of Header dump ==\n" ); + return ret; +} + + +void print_copyright() +{ + printf ( "Part of bcm-utils package ver. " UTIL_VERSION " \n" ); + printf ( "Copyright (C) 2009 Andrew 'Necromant' Andrianov\n" + "This is free software, and you are welcome to redistribute it\n" + "under certain conditions. See COPYING for details\n" ); +} diff --git a/tools/firmware-utils/src/bcmalgo.h b/tools/firmware-utils/src/bcmalgo.h new file mode 100644 index 00000000000..46647cf6d3d --- /dev/null +++ b/tools/firmware-utils/src/bcmalgo.h @@ -0,0 +1,83 @@ +#ifndef bcmutils_H +#define bcmutils_H + +typedef struct +{ + uint16_t magic; + uint16_t control; + uint16_t rev_maj; + uint16_t rev_min; + uint32_t build_date; + uint32_t filelen; + uint32_t ldaddress; + char filename[64]; + uint16_t hcs; + uint16_t her_znaet_chto; //v dushe ne ebu + uint32_t crc; +} ldr_header_t; + + +/** + * Reverses endianess of a 32bit int, if the ENDIAN_REVERSE_NEEDED defined at compile-time + * @param data + * @return + */ +uint32_t reverse_endian32 ( uint32_t data ); + +/** + * Reverses endianess of a 16bit int, if the ENDIAN_REVERSE_NEEDED defined at compile-time + * @param data + * @return + */ +uint16_t reverse_endian16 ( uint16_t data ); +/** + * Calculates the strange crc (used by bcm modems) of the file. Thnx fly out to Vector for the algorithm. + * @param filename + * @return + */ +uint32_t get_file_crc ( char* filename ); + +/** + * Calculates HCS of the header. + * @param hd + * @return + */ +uint16_t get_hcs ( ldr_header_t* hd ); + +/** + * Constructs the header of the image with the information given It also automagically calculates HCS and writes it there. + * @param magic - magic device bytes + * @param rev_maj - major revision + * @param rev_min - minor revision + * @param build_date - build date (seconds from EPOCH UTC) + * @param filelen - file length in bytes + * @param ldaddress - Load adress + * @param filename - filename + * @param crc_data - the crc of the data + * @return + */ +ldr_header_t* construct_header ( uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc_data ); + +/** + * Dumps header information to stdout. + * @param hd + */ +int dump_header ( ldr_header_t* hd ); + + +/** + * Returns a null terminated string describing what the control number meens + * DO NOT FREE IT!!! + * @param control + * @return + */ +char* get_control_info ( uint16_t control ); +#endif + +/** + * Calculates bcmCRC of a data buffer. + * @param filebuffer - pointer to buffer + * @param size - buffer size + * @return + */ +uint32_t get_buffer_crc ( char* filebuffer, size_t size ); diff --git a/tools/firmware-utils/src/buffalo-enc.c b/tools/firmware-utils/src/buffalo-enc.c index 13d270b3f73..08fad4ee61b 100644 --- a/tools/firmware-utils/src/buffalo-enc.c +++ b/tools/firmware-utils/src/buffalo-enc.c @@ -34,6 +34,8 @@ static unsigned char seed = 'O'; static char *product; static char *version; static int do_decrypt; +static int offset; +static int size; void usage(int status) { @@ -52,6 +54,8 @@ void usage(int status) " -p <product> set product name to <product>\n" " -v <version> set version to <version>\n" " -h show this screen\n" +" -O Offset of encrypted data in file (decryption)\n" +" -S Size of unencrypted data in file (encryption)\n" ); exit(status); @@ -85,8 +89,9 @@ static int decrypt_file(void) memset(&ep, '\0', sizeof(ep)); ep.key = (unsigned char *) crypt_key; + ep.longstate = longstate; - err = decrypt_buf(&ep, buf, src_len); + err = decrypt_buf(&ep, buf + offset, src_len - offset); if (err) { ERR("unable to decrypt '%s'", ifname); goto out; @@ -99,7 +104,7 @@ static int decrypt_file(void) printf("Data len\t: %u\n", ep.datalen); printf("Checksum\t: 0x%08x\n", ep.csum); - err = write_buf_to_file(ofname, buf, ep.datalen); + err = write_buf_to_file(ofname, buf + offset, ep.datalen); if (err) { ERR("unable to write to file '%s'", ofname); goto out; @@ -115,7 +120,7 @@ out: static int encrypt_file(void) { struct enc_param ep; - ssize_t src_len; + ssize_t src_len, tail_dst, tail_len, tail_src; unsigned char *buf; uint32_t hdrlen; ssize_t totlen = 0; @@ -128,8 +133,12 @@ static int encrypt_file(void) goto out; } - totlen = enc_compute_buf_len(product, version, src_len); - hdrlen = enc_compute_header_len(product, version); + if (size) { + tail_dst = enc_compute_buf_len(product, version, size); + tail_len = src_len - size; + totlen = tail_dst + tail_len; + } else + totlen = enc_compute_buf_len(product, version, src_len); buf = malloc(totlen); if (buf == NULL) { @@ -137,12 +146,21 @@ static int encrypt_file(void) goto out; } + hdrlen = enc_compute_header_len(product, version); + err = read_file_to_buf(ifname, &buf[hdrlen], src_len); if (err) { ERR("unable to read from file '%s'", ofname); goto free_buf; } + if (size) { + tail_src = hdrlen + size; + memmove(&buf[tail_dst], &buf[tail_src], tail_len); + memset(&buf[tail_src], 0, tail_dst - tail_src); + src_len = size; + } + memset(&ep, '\0', sizeof(ep)); ep.key = (unsigned char *) crypt_key; ep.seed = seed; @@ -238,7 +256,7 @@ int main(int argc, char *argv[]) while ( 1 ) { int c; - c = getopt(argc, argv, "adi:m:o:hp:v:k:r:s:"); + c = getopt(argc, argv, "adi:m:o:hlp:v:k:O:r:s:S:"); if (c == -1) break; @@ -270,6 +288,12 @@ int main(int argc, char *argv[]) case 's': seed = strtoul(optarg, NULL, 16); break; + case 'O': + offset = strtoul(optarg, NULL, 0); + break; + case 'S': + size = strtoul(optarg, NULL, 0); + break; case 'h': usage(EXIT_SUCCESS); break; diff --git a/tools/firmware-utils/src/buffalo-lib.c b/tools/firmware-utils/src/buffalo-lib.c index 29aee9f88dd..b1d5ede0a28 100644 --- a/tools/firmware-utils/src/buffalo-lib.c +++ b/tools/firmware-utils/src/buffalo-lib.c @@ -179,7 +179,7 @@ int bcrypt_buf(unsigned char seed, unsigned char *key, unsigned char *src, uint32_t buffalo_csum(uint32_t csum, void *buf, unsigned long len) { - char *p = buf; + signed char *p = buf; while (len--) { int i; @@ -249,10 +249,10 @@ static uint32_t get_be32(void *data) static int check_magic(void *magic) { - if (!memcmp("start", magic, ENC_MAGIC_LEN)); + if (!memcmp("start", magic, ENC_MAGIC_LEN)) return 0; - if (!memcmp("asar1", magic, ENC_MAGIC_LEN)); + if (!memcmp("asar1", magic, ENC_MAGIC_LEN)) return 0; return -1; diff --git a/tools/firmware-utils/src/buffalo-lib.h b/tools/firmware-utils/src/buffalo-lib.h index ba8a5081294..7eb9bf53987 100644 --- a/tools/firmware-utils/src/buffalo-lib.h +++ b/tools/firmware-utils/src/buffalo-lib.h @@ -69,6 +69,26 @@ struct buffalo_tag2 { uint8_t unknown2[3]; } __attribute ((packed)); +struct buffalo_tag3 { + unsigned char product[TAG_PRODUCT_LEN]; + unsigned char brand[TAG_BRAND_LEN]; + unsigned char ver_major[TAG_VERSION_LEN]; + unsigned char ver_minor[TAG_VERSION_LEN]; + unsigned char region_code[2]; + uint32_t region_mask; + unsigned char unknown0[2]; + unsigned char language[TAG_LANGUAGE_LEN]; + unsigned char platform[TAG_PLATFORM_LEN]; + unsigned char hwv[TAG_HWVER_LEN]; + unsigned char hwv_val[TAG_HWVER_VAL_LEN]; + uint8_t unknown1[24]; + + uint32_t total_len; + uint32_t crc; + uint32_t len1; + uint32_t base2; +} __attribute ((packed)); + #define ENC_PRODUCT_LEN 32 #define ENC_VERSION_LEN 8 #define ENC_MAGIC_LEN 6 diff --git a/tools/firmware-utils/src/buffalo-tag.c b/tools/firmware-utils/src/buffalo-tag.c index b5db72ef968..6d479f7fba9 100644 --- a/tools/firmware-utils/src/buffalo-tag.c +++ b/tools/firmware-utils/src/buffalo-tag.c @@ -48,6 +48,7 @@ static uint32_t base2; static char *region_code; static uint32_t region_mask; static int num_regions; +static int dhp; void usage(int status) { @@ -63,6 +64,7 @@ void usage(int status) " -d <base2>\n" " -f <flag> set flag to <flag>\n" " -i <file> read input from the file <file>\n" +" -I <file> read input from the file <file> for DHP series\n" " -l <language> set language to <language>\n" " -m <version> set minor version to <version>\n" " -o <file> write output to the file <file>\n" @@ -227,6 +229,37 @@ static void fixup_tag2(unsigned char *buf, ssize_t buflen) tag->crc = htonl(buffalo_crc(buf, buflen)); } +static void fixup_tag3(unsigned char *buf, ssize_t totlen) +{ + struct buffalo_tag3 *tag = (struct buffalo_tag3 *) buf; + + memset(tag, '\0', sizeof(*tag)); + + memcpy(tag->brand, brand, strlen(brand)); + memcpy(tag->product, product, strlen(product)); + memcpy(tag->platform, platform, strlen(platform)); + memcpy(tag->ver_major, major, strlen(major)); + memcpy(tag->ver_minor, minor, strlen(minor)); + memcpy(tag->language, language, strlen(language)); + + if (num_regions > 1) { + tag->region_code[0] = 'M'; + tag->region_code[1] = '_'; + tag->region_mask = htonl(region_mask); + } else { + memcpy(tag->region_code, region_code, 2); + } + + tag->total_len = htonl(totlen); + tag->len1 = htonl(fsize[0]); + tag->base2 = htonl(base2); + + if (hwver) { + memcpy(tag->hwv, "hwv", 3); + memcpy(tag->hwv_val, hwver, strlen(hwver)); + } +} + static int tag_file(void) { unsigned char *buf; @@ -237,7 +270,9 @@ static int tag_file(void) int ret = -1; int i; - if (num_files == 1) + if (dhp) + hdrlen = sizeof(struct buffalo_tag3); + else if (num_files == 1) hdrlen = sizeof(struct buffalo_tag); else hdrlen = sizeof(struct buffalo_tag2); @@ -270,7 +305,9 @@ static int tag_file(void) offset += fsize[i]; } - if (num_files == 1) + if (dhp) + fixup_tag3(buf, fsize[0] + 200); + else if (num_files == 1) fixup_tag(buf, buflen); else fixup_tag2(buf, buflen); @@ -299,7 +336,7 @@ int main(int argc, char *argv[]) while ( 1 ) { int c; - c = getopt(argc, argv, "a:b:c:d:f:hi:l:m:o:p:r:sv:w:"); + c = getopt(argc, argv, "a:b:c:d:f:hi:l:m:o:p:r:sv:w:I:"); if (c == -1) break; @@ -319,6 +356,9 @@ int main(int argc, char *argv[]) case 'f': flag = strtoul(optarg, NULL, 2); break; + case 'I': + dhp = 1; + /* FALLTHROUGH */ case 'i': err = process_ifname(optarg); if (err) diff --git a/tools/firmware-utils/src/buffalo-tftp.c b/tools/firmware-utils/src/buffalo-tftp.c index 1a2551a41c7..087f9955b64 100644 --- a/tools/firmware-utils/src/buffalo-tftp.c +++ b/tools/firmware-utils/src/buffalo-tftp.c @@ -70,7 +70,6 @@ static int crypt_file(void) { unsigned char *buf = NULL; ssize_t src_len; - ssize_t crypt_len; int err; int ret = -1; @@ -92,7 +91,6 @@ static int crypt_file(void) goto out; } - crypt_len = (src_len > 512) ? 512 : src_len; if (do_decrypt) crypt_header(buf, 512, crypt_key2, crypt_key1); else diff --git a/tools/firmware-utils/src/csysimg.h b/tools/firmware-utils/src/csysimg.h index 19dfbd4334c..65ab062f31e 100644 --- a/tools/firmware-utils/src/csysimg.h +++ b/tools/firmware-utils/src/csysimg.h @@ -49,6 +49,7 @@ #define SIG_BR6114WG SIG_BR6104IPC #define SIG_BR6524K "2-K-" #define SIG_BR6524KP "2-KP" /* FIXME: valid? */ +#define SIG_BR6524N "WNRA" #define SIG_BR6524WG "2-WG" /* FIXME: valid? */ #define SIG_BR6524WP "2-WP" /* FIXME: valid? */ #define SIG_BR6541K "4--K" diff --git a/tools/firmware-utils/src/dgfirmware.c b/tools/firmware-utils/src/dgfirmware.c index 5ff3b69646d..e3257f10779 100644 --- a/tools/firmware-utils/src/dgfirmware.c +++ b/tools/firmware-utils/src/dgfirmware.c @@ -1,5 +1,6 @@ #include <stdlib.h> #include <stdio.h> +#include <string.h> #define IMG_SIZE 0x3e0000 diff --git a/tools/firmware-utils/src/dgn3500sum.c b/tools/firmware-utils/src/dgn3500sum.c new file mode 100644 index 00000000000..eb80e6c01b0 --- /dev/null +++ b/tools/firmware-utils/src/dgn3500sum.c @@ -0,0 +1,166 @@ +/* ************************************************************************** + + This program creates a modified 16bit checksum used for the Netgear + DGN3500 series routers. The difference between this and a standard + checksum is that every 0x100 bytes added 0x100 have to be subtracted + from the sum. + + (C) 2013 Marco Antonio Mauro <marcus90 at gmail.com> + + Based on previous unattributed work. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + ************************************************************************* */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> + +unsigned char PidDataWW[70] = +{ + 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32, + 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, + 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, +} ; + +unsigned char PidDataDE[70] = +{ + 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x37, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, + 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, +} ; + +unsigned char PidDataNA[70] = +{ + 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, + 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, +} ; + +/* ******************************************************************* + Reads the file into memory and returns pointer to the buffer. */ +static char *readfile(char *filename, int *size) +{ + FILE *fp; + char *buffer; + struct stat info; + + if (stat(filename,&info)!=0) + return NULL; + + if ((fp=fopen(filename,"r"))==NULL) + return NULL; + + buffer=NULL; + for (;;) + { + if ((buffer=(char *)malloc(info.st_size+1))==NULL) + break; + + if (fread(buffer,1,info.st_size,fp)!=info.st_size) + { + free(buffer); + buffer=NULL; + break; + } + + buffer[info.st_size]='\0'; + if(size) *size = info.st_size; + + break; + } + + (void)fclose(fp); + + return buffer; +} + + +/* ******************************************************************* */ +int main(int argc, char** argv) +{ + unsigned long start, i; + char *endptr, *buffer, *p; + int count; // size of file in bytes + unsigned short sum = 0, sum1 = 0; + char sumbuf[9]; + + if(argc < 3) { + printf("ERROR: Argument missing!\n\nUsage %s filename starting offset in hex [PID code]\n\n", argv[0]); + return 1; + } + + + FILE *fp = fopen(argv[1], "a"); + if(!fp) { + printf("ERROR: File not writeable!\n"); + return 1; + } + if(argc == 4) + { + printf("%s: PID type: %s\n", argv[0], argv[3]); + if(strcmp(argv[3], "DE")==0) + fwrite(PidDataDE, sizeof(PidDataDE), sizeof(char), fp); /* write DE pid */ + else if(strcmp(argv[3], "NA")==0) + fwrite(PidDataNA, sizeof(PidDataNA), sizeof(char), fp); /* write NA pid */ + else /* if(strcmp(argv[3], "WW")) */ + fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid */ + } + else + fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid if unspecified */ + + fclose(fp); + + /* Read the file to calculate the checksums */ + buffer = readfile(argv[1], &count); + if(!buffer) { + printf("ERROR: File %s not found!\n", argv[1]); + return 1; + } + + p = buffer; + for(i = 0; i < count; i++) + { + sum += p[i]; + } + + start = strtol(argv[2], &endptr, 16); + p = buffer+start; + for(i = 0; i < count - start; i++) + { + sum1 += p[i]; + } + + sprintf(sumbuf,"%04X%04X",sum1,sum); + /* Append the 2 checksums to end of file */ + fp = fopen(argv[1], "a"); + if(!fp) { + printf("ERROR: File not writeable!\n"); + return 1; + } + fwrite(sumbuf, 8, sizeof(char), fp); + fclose(fp); + free(buffer); + return 0; +} diff --git a/tools/firmware-utils/src/dns313-header.c b/tools/firmware-utils/src/dns313-header.c new file mode 100644 index 00000000000..e69e57e7baa --- /dev/null +++ b/tools/firmware-utils/src/dns313-header.c @@ -0,0 +1,239 @@ +/* + * dns313-header.c + * + * Program to add the modified U-Boot header to a binary used with + * the D-Link DNS-313 boot loader when booting directly from an + * EXT2 formatted hard drive. + * + * The DNS313 use the same header on zImage, ramdisk, rootfs. + * + * Written by Linus Walleij <linus.walleij@linaro.org> + * License terms: GPLv2 + */ +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <stdint.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +/* + * This is the U-Boot magic number, so the U-Boot header was used + * (obviously) as a template for this custom header. + */ +#define IH_MAGIC 0x27051956 +#define HEADER_SIZE 0x68 + +#define OFFSET_MAGIC 0x00 +#define OFFSET_HCRC 0x04 +#define OFFSET_TIME 0x08 +#define OFFSET_SIZE 0x0c +#define OFFSET_LOAD 0x10 +#define OFFSET_EP 0x14 +#define OFFSET_DCRC 0x18 +#define OFFSET_OS 0x1c +#define OFFSET_ARCH 0x1d +#define OFFSET_TYPE 0x1e +#define OFFSET_COMP 0x1f +#define OFFSET_NAME 0x20 +#define NAME_LEN 0x20 +#define OFFSET_MODEL 0x40 +#define MODEL_LEN 0x10 +#define OFFSET_VERSION 0x50 +#define VERSION_LEN 0x10 +#define OFFSET_MAC 0x60 +#define MAC_LEN 6 + +static const uint32_t crc32_table[256] = { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +}; + +static uint32_t crc32(uint32_t crc, + const unsigned char *buf, + unsigned int len) +{ + crc = crc ^ 0xffffffffUL; + do { + crc = crc32_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); + } while (--len); + return crc ^ 0xffffffffUL; +} + +static void be_wr(unsigned char *buf, uint32_t val) +{ + buf[0] = (val >> 24) & 0xFFU; + buf[1] = (val >> 16) & 0xFFU; + buf[2] = (val >> 8) & 0xFFU; + buf[3] = val & 0xFFU; +} + +int main(int argc, char **argv) +{ + int fdin; + int fdout; + struct stat sb; + uint32_t filesize; + uint32_t padding; + int ret = 0; + const char *pathin; + const char *pathout; + unsigned char *buffer; + unsigned char *infop; + uint32_t sum; + size_t bufsize; + size_t bytes; + int i; + + if (argc < 3) { + printf("Too few arguments.\n"); + printf("%s <infile> <outfile>\n", argv[0]); + } + + pathin = argv[1]; + pathout = argv[2]; + + ret = stat(pathin, &sb); + if (ret < 0) + return ret; + + filesize = sb.st_size; + padding = filesize % 4; + printf("INFILE: %s, size: %08x bytes\n", pathin, filesize); + /* File + extended header size */ + bufsize = filesize + HEADER_SIZE; + + printf("Allocate %08x bytes\n", bufsize); + buffer = malloc(bufsize); + if (!buffer) { + printf("OOM: could not allocate buffer\n"); + return 0; + } + + memset(buffer, 0x00, bufsize); + + /* Read file to buffer */ + fdin = open(pathin, O_RDONLY); + if (!fdin) { + printf("ERROR: could not open input file\n"); + return 0; + } + bytes = read(fdin, buffer + HEADER_SIZE, filesize); + if (bytes < filesize) { + printf("ERROR: could not read entire file\n"); + return 0; + } + close(fdin); + + /* PREP HEADER AND FOOTER */ + infop = buffer; + + be_wr(buffer + OFFSET_MAGIC, IH_MAGIC); + + /* FIXME: use actual time */ + be_wr(buffer + OFFSET_TIME, 0x4c06738c); + be_wr(buffer + OFFSET_SIZE, filesize); + + /* Load address & entry point */ + be_wr(buffer + OFFSET_LOAD, 0x00008000); + be_wr(buffer + OFFSET_EP, 0x00008000); + + buffer[OFFSET_OS] = 0x05; /* Linux */ + buffer[OFFSET_ARCH] = 0x02; /* ARM */ + buffer[OFFSET_TYPE] = 0x02; /* OS kernel image */ + buffer[OFFSET_COMP] = 0x01; /* gzip */ + + /* The vendor firmware just hardcodes this */ + strncpy(buffer + OFFSET_NAME, "kernel.img", NAME_LEN); + buffer[OFFSET_NAME + NAME_LEN - 1] = '\0'; + strncpy(buffer + OFFSET_MODEL, "dns-313v3", MODEL_LEN); + buffer[OFFSET_MODEL + MODEL_LEN - 1] = '\0'; + strncpy(buffer + OFFSET_VERSION, "2.01b04", VERSION_LEN); + buffer[OFFSET_VERSION + VERSION_LEN - 1] = '\0'; + /* Just some MAC address from the example */ + buffer[OFFSET_MAC] = 0x00; + buffer[OFFSET_MAC + 1] = 0x80; + buffer[OFFSET_MAC + 2] = 0xc8; + buffer[OFFSET_MAC + 3] = 0x16; + buffer[OFFSET_MAC + 4] = 0x81; + buffer[OFFSET_MAC + 5] = 0x68; + + /* Checksum payload */ + sum = crc32(0, buffer + HEADER_SIZE, filesize); + be_wr(buffer + OFFSET_DCRC, sum); + printf("data checksum: 0x%08x\n", sum); + + /* Checksum header, then write that into the header checksum */ + sum = crc32(0, buffer, HEADER_SIZE); + be_wr(buffer + OFFSET_HCRC, sum); + printf("header checksum: 0x%08x\n", sum); + + printf("OUTFILE: %s, size: %08x bytes\n", pathout, bufsize); + fdout = open(pathout, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU|S_IRGRP); + if (!fdout) { + printf("ERROR: could not open output file\n"); + return 0; + } + bytes = write(fdout, buffer, bufsize); + if (bytes < bufsize) { + printf("ERROR: could not write complete output file\n"); + return 0; + } + close(fdout); + + free(buffer); + + return 0; +} diff --git a/tools/firmware-utils/src/edimax_fw_header.c b/tools/firmware-utils/src/edimax_fw_header.c new file mode 100644 index 00000000000..b85e3a1781c --- /dev/null +++ b/tools/firmware-utils/src/edimax_fw_header.c @@ -0,0 +1,386 @@ +/* + * Copyright (C) 2014 Gabor Juhos <juhosg@openwrt.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> /* for unlink() */ +#include <libgen.h> +#include <getopt.h> /* for getopt() */ +#include <stdarg.h> +#include <errno.h> +#include <sys/stat.h> + +#include <arpa/inet.h> +#include <netinet/in.h> + +#define MAX_MAGIC_LEN 16 +#define MAX_MODEL_LEN 32 +#define MAX_VERSION_LEN 14 +#define MAX_MTD_NAME_LEN 16 + +#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) + +struct edimax_header { + char magic[MAX_MAGIC_LEN]; + char model[MAX_MODEL_LEN]; + unsigned char force; + unsigned char header_csum; + unsigned char data_csum; + uint32_t data_size; + uint32_t start_addr; + uint32_t end_addr; + char fw_version[MAX_VERSION_LEN]; + unsigned char type; + char mtd_name[MAX_MTD_NAME_LEN]; +} __attribute__ ((packed)); + +/* + * Globals + */ +static char *ofname; +static char *ifname; +static char *progname; + +static char *model; +static char *magic = "eDiMaX"; +static char *fw_version = ""; +static char *mtd_name; +static int force; +static uint32_t start_addr; +static uint32_t end_addr; +static uint8_t image_type; +static int data_size; + +/* + * Message macros + */ +#define ERR(fmt, ...) do { \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt "\n", \ + progname, ## __VA_ARGS__ ); \ +} while (0) + +#define ERRS(fmt, ...) do { \ + int save = errno; \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt " (%s)\n", \ + progname, ## __VA_ARGS__, strerror(save)); \ +} while (0) + +#define DBG(fmt, ...) do { \ + fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ +} while (0) + +static void usage(int status) +{ + FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; + + fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stream, +"\n" +"Options:\n" +" -e <addr> set end addr to <addr>\n" +" -f set force flag\n" +" -h show this screen\n" +" -i <file> read input data from the file <file>\n" +" -o <file> write output to the file <file>\n" +" -m <model> set model to <model>\n" +" -M <magic> set image magic to <magic>\n" +" -n <name> set MTD device name to <name>\n" +" -s <addr> set start address to <addr>\n" +" -t <type> set image type to <type>\n" +" -v <version> set firmware version to <version>\n" + ); + + exit(status); +} + +int +str2u32(char *arg, uint32_t *val) +{ + char *err = NULL; + uint32_t t; + + errno=0; + t = strtoul(arg, &err, 0); + if (errno || (err==arg) || ((err != NULL) && *err)) { + return -1; + } + + *val = t; + return 0; +} + +int +str2u8(char *arg, uint8_t *val) +{ + char *err = NULL; + uint32_t t; + + errno=0; + t = strtoul(arg, &err, 0); + if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x100)) { + return -1; + } + + *val = t & 0xFF; + return 0; +} + +static int get_file_size(char *name) +{ + struct stat st; + int res; + + res = stat(name, &st); + if (res){ + ERRS("stat failed on %s", name); + return -1; + } + + return st.st_size; +} + +static int read_to_buf(char *name, char *buf, int buflen) +{ + FILE *f; + int ret = EXIT_FAILURE; + + f = fopen(name, "r"); + if (f == NULL) { + ERRS("could not open \"%s\" for reading", name); + goto out; + } + + errno = 0; + fread(buf, buflen, 1, f); + if (errno != 0) { + ERRS("unable to read from file \"%s\"", name); + goto out_close; + } + + ret = EXIT_SUCCESS; + +out_close: + fclose(f); +out: + return ret; +} + +static int check_options(void) +{ +#define CHKSTR(_name, _msg) \ + do { \ + if (_name == NULL) { \ + ERR("no %s specified", _msg); \ + return -1; \ + } \ + } while (0) + +#define CHKSTRLEN(_name, _msg) \ + do { \ + int field_len; \ + CHKSTR(_name, _msg); \ + field_len = FIELD_SIZEOF(struct edimax_header, _name) - 1; \ + if (strlen(_name) > field_len) { \ + ERR("'%s' is too long, max %s length is %d", \ + _name, _msg, field_len); \ + return -1; \ + } \ + } while (0) + + CHKSTR(ofname, "output file"); + CHKSTR(ifname, "input file"); + + CHKSTRLEN(magic, "magic"); + CHKSTRLEN(model, "model"); + CHKSTRLEN(mtd_name, "MTD device name"); + CHKSTRLEN(fw_version, "firware version"); + + data_size = get_file_size(ifname); + if (data_size < 0) + return -1; + + return 0; +} + +static int write_fw(char *data, int len) +{ + FILE *f; + int ret = EXIT_FAILURE; + + f = fopen(ofname, "w"); + if (f == NULL) { + ERRS("could not open \"%s\" for writing", ofname); + goto out; + } + + errno = 0; + fwrite(data, len, 1, f); + if (errno) { + ERRS("unable to write output file"); + goto out_flush; + } + + DBG("firmware file \"%s\" completed", ofname); + + ret = EXIT_SUCCESS; + +out_flush: + fflush(f); + fclose(f); + if (ret != EXIT_SUCCESS) { + unlink(ofname); + } +out: + return ret; +} + +static unsigned char checksum(unsigned char *p, unsigned len) +{ + unsigned char csum = 0; + + while (len--) + csum += *p++; + + csum ^= 0xb9; + + return csum; +} + +static int build_fw(void) +{ + int buflen; + char *buf; + char *data; + struct edimax_header *hdr; + int ret = EXIT_FAILURE; + + buflen = sizeof(struct edimax_header) + data_size; + + buf = malloc(buflen); + if (!buf) { + ERR("no memory for buffer\n"); + goto out; + } + + data = buf + sizeof(struct edimax_header); + + /* read input file */ + ret = read_to_buf(ifname, data, data_size); + if (ret) + goto out_free_buf; + + /* fill firmware header */ + hdr = (struct edimax_header *)buf; + memset(hdr, 0, sizeof(struct edimax_header)); + + strncpy(hdr->model, model, sizeof(hdr->model)); + strncpy(hdr->magic, magic, sizeof(hdr->magic)); + strncpy(hdr->fw_version, fw_version, sizeof(hdr->fw_version)); + strncpy(hdr->mtd_name, mtd_name, sizeof(hdr->mtd_name)); + + hdr->force = force; + hdr->start_addr = htonl(start_addr); + hdr->end_addr = htonl(end_addr); + hdr->data_size = htonl(data_size); + hdr->type = image_type; + + hdr->data_csum = checksum((unsigned char *)data, data_size); + hdr->header_csum = checksum((unsigned char *)hdr, + sizeof(struct edimax_header)); + + ret = write_fw(buf, buflen); + if (ret) + goto out_free_buf; + + ret = EXIT_SUCCESS; + +out_free_buf: + free(buf); +out: + return ret; +} + +int main(int argc, char *argv[]) +{ + int ret = EXIT_FAILURE; + + progname = basename(argv[0]); + + while (1) { + int c; + + c = getopt(argc, argv, "e:fhi:o:m:M:n:s:t:v:"); + if (c == -1) + break; + + switch (c) { + case 'e': + if (str2u32(optarg, &end_addr)) { + ERR("%s is invalid '%s'", + "end address", optarg); + goto out; + } + break; + case 'f': + force = 1; + break; + case 'i': + ifname = optarg; + break; + case 'h': + usage(EXIT_SUCCESS); + break; + case 'o': + ofname = optarg; + break; + case 'm': + model = optarg; + break; + case 'M': + magic = optarg; + break; + case 'n': + mtd_name = optarg; + break; + case 's': + if (str2u32(optarg, &start_addr)) { + ERR("%s is invalid '%s'", + "start address", optarg); + goto out; + } + break; + case 't': + if (str2u8(optarg, &image_type)) { + ERR("%s is invalid '%s'", + "image type", optarg); + goto out; + } + break; + case 'v': + fw_version = optarg; + break; + default: + usage(EXIT_FAILURE); + break; + } + } + + ret = check_options(); + if (ret) + goto out; + + ret = build_fw(); + +out: + return ret; +} diff --git a/tools/firmware-utils/src/fix-u-media-header.c b/tools/firmware-utils/src/fix-u-media-header.c new file mode 100644 index 00000000000..21f184e66da --- /dev/null +++ b/tools/firmware-utils/src/fix-u-media-header.c @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> /* for unlink() */ +#include <libgen.h> +#include <getopt.h> /* for getopt() */ +#include <stdarg.h> +#include <errno.h> +#include <sys/stat.h> + +#include "cyg_crc.h" + +#include <arpa/inet.h> +#include <netinet/in.h> + +#define IH_MAGIC 0x27051956 /* Image Magic Number */ +#define IH_NMLEN 32 /* Image Name Length */ + +#define UM_MAGIC 0x55525F46 +#define UM_HEADER_LEN 12 + +/* + * all data in network byte order (aka natural aka bigendian) + */ +struct u_media_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + uint8_t ih_name[IH_NMLEN - UM_HEADER_LEN]; /* Image Name */ + + uint32_t ih_UMedia_magic; /* U-Media magic number */ + uint32_t ih_UMedia_boardID; /* U-Media board ID */ + uint8_t ih_UMedia_imageType; /* U-Media image type */ + uint8_t ih_UMedia_LoadDefault; /* U-Media load to factory default setting */ + uint8_t ih_UMedia_temp1; /* U-Media didn't use this tag */ + uint8_t ih_UMedia_temp2; /* U-Media didn't use this tag */ +} __attribute__ ((packed)); + +struct if_info { + char *file_name; /* name of the file */ + uint32_t file_size; /* length of the file */ +}; + +static char *progname; +static char *ofname; +static struct if_info if_info; +static int factory_defaults; +static uint32_t board_id; +static uint8_t image_type; + +/* + * Message macros + */ +#define ERR(fmt, ...) do { \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt "\n", \ + progname, ## __VA_ARGS__ ); \ +} while (0) + +#define ERRS(fmt, ...) do { \ + int save = errno; \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt " (%s)\n", \ + progname, ## __VA_ARGS__, strerror(save)); \ +} while (0) + +#define DBG(fmt, ...) do { \ + fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ +} while (0) + +static void usage(int status) +{ + FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; + + fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stream, +"\n" +"Options:\n" +" -B <board_id> set board ID to <board_id>\n" +" -i <file> read input from the file <file>\n" +" -F load factory defaults\n" +" -o <file> write output to the file <file>\n" +" -T <type> set image type to <type>\n" +" -h show this screen\n" + ); + + exit(status); +} + +static int str2u32(char *arg, uint32_t *val) +{ + char *err = NULL; + uint32_t t; + + errno=0; + t = strtoul(arg, &err, 0); + if (errno || (err==arg) || ((err != NULL) && *err)) { + return -1; + } + + *val = t; + return 0; +} + +static int str2u8(char *arg, uint8_t *val) +{ + char *err = NULL; + uint32_t t; + + errno=0; + t = strtoul(arg, &err, 0); + if (errno || (err==arg) || ((err != NULL) && *err)) { + return -1; + } + + if (t > 255) + return -1; + + *val = t; + return 0; +} + +static int get_file_stat(struct if_info *fdata) +{ + struct stat st; + int res; + + if (fdata->file_name == NULL) + return 0; + + res = stat(fdata->file_name, &st); + if (res){ + ERRS("stat failed on %s", fdata->file_name); + return res; + } + + fdata->file_size = st.st_size; + return 0; +} + +static int read_to_buf(struct if_info *fdata, char *buf) +{ + FILE *f; + int ret = EXIT_FAILURE; + + f = fopen(fdata->file_name, "r"); + if (f == NULL) { + ERRS("could not open \"%s\" for reading", fdata->file_name); + goto out; + } + + errno = 0; + fread(buf, fdata->file_size, 1, f); + if (errno != 0) { + ERRS("unable to read from file \"%s\"", fdata->file_name); + goto out_close; + } + + ret = EXIT_SUCCESS; + +out_close: + fclose(f); +out: + return ret; +} + +static int check_options(void) +{ + int ret; + + if (ofname == NULL) { + ERR("no %s specified", "output file"); + return -1; + } + + if (if_info.file_name == NULL) { + ERR("no %s specified", "input file"); + return -1; + } + + ret = get_file_stat(&if_info); + if (ret) + return ret; + + return 0; +} + +static int write_fw(char *data, int len) +{ + FILE *f; + int ret = EXIT_FAILURE; + + f = fopen(ofname, "w"); + if (f == NULL) { + ERRS("could not open \"%s\" for writing", ofname); + goto out; + } + + errno = 0; + fwrite(data, len, 1, f); + if (errno) { + ERRS("unable to write output file"); + goto out_flush; + } + + ret = EXIT_SUCCESS; + +out_flush: + fflush(f); + fclose(f); + if (ret != EXIT_SUCCESS) { + unlink(ofname); + } +out: + return ret; +} + +static int fix_header(void) +{ + int buflen; + char *buf; + uint32_t crc, crc_orig; + struct u_media_header *hdr; + int ret = EXIT_FAILURE; + + buflen = if_info.file_size; + if (buflen < sizeof(*hdr)) { + ERR("invalid input file\n"); + return ret; + } + + buf = malloc(buflen); + if (!buf) { + ERR("no memory for buffer\n"); + goto out; + } + + ret = read_to_buf(&if_info, buf); + if (ret) + goto out_free_buf; + + hdr = (struct u_media_header *) buf; + if (ntohl(hdr->ih_magic) != IH_MAGIC) { + ERR("invalid input file, bad magic\n"); + goto out_free_buf; + } + + /* verify header CRC */ + crc_orig = ntohl(hdr->ih_hcrc); + hdr->ih_hcrc = 0; + crc = cyg_ether_crc32((unsigned char *)hdr, sizeof(*hdr)); + if (crc != crc_orig) { + ERR("invalid input file, bad header CRC\n"); + goto out_free_buf; + } + + hdr->ih_name[IH_NMLEN - UM_HEADER_LEN - 1] = '\0'; + + /* set U-Media specific fields */ + hdr->ih_UMedia_magic = htonl(UM_MAGIC); + hdr->ih_UMedia_boardID = htonl(board_id); + hdr->ih_UMedia_imageType = image_type; + hdr->ih_UMedia_LoadDefault = (factory_defaults) ? 1 : 0; + + /* update header CRC */ + crc = cyg_ether_crc32((unsigned char *)hdr, sizeof(*hdr)); + hdr->ih_hcrc = htonl(crc); + + ret = write_fw(buf, buflen); + if (ret) + goto out_free_buf; + + DBG("U-Media header fixed in \"%s\"", ofname); + + ret = EXIT_SUCCESS; + +out_free_buf: + free(buf); +out: + return ret; +} + +int main(int argc, char *argv[]) +{ + int ret = EXIT_FAILURE; + + progname = basename(argv[0]); + + while (1) { + int c; + + c = getopt(argc, argv, "B:Fi:o:T:h"); + if (c == -1) + break; + + switch (c) { + case 'B': + if (str2u32(optarg, &board_id)) { + ERR("%s is invalid '%s'", + "board ID", optarg); + goto out; + } + break; + case 'T': + if (str2u8(optarg, &image_type)) { + ERR("%s is invalid '%s'", + "image type", optarg); + goto out; + } + break; + case 'F': + factory_defaults = 1; + break; + case 'i': + if_info.file_name = optarg; + break; + case 'o': + ofname = optarg; + break; + case 'h': + usage(EXIT_SUCCESS); + break; + default: + usage(EXIT_FAILURE); + break; + } + } + + ret = check_options(); + if (ret) + goto out; + + ret = fix_header(); + +out: + return ret; +} diff --git a/tools/firmware-utils/src/hcsmakeimage.c b/tools/firmware-utils/src/hcsmakeimage.c new file mode 100644 index 00000000000..7baa7b5845e --- /dev/null +++ b/tools/firmware-utils/src/hcsmakeimage.c @@ -0,0 +1,203 @@ +#include <stdlib.h> +#include <sys/types.h> +#include <stdio.h> +#include <inttypes.h> +#include <string.h> +#include <getopt.h> +#include <unistd.h> +#include <errno.h> +#include <time.h> +#include <sys/stat.h> +#include <libgen.h> +#include "bcmalgo.h" + + +int flag_print_version; +int flag_print_help; +int flag_compress; + +uint16_t sa2100_magic = 0x2100; +uint16_t sa3349_magic = 0x3349; +uint32_t default_date = 0x00000000; //A long time ago in a galaxy far far away.... +uint32_t default_load_address = 0x80010000; //The default load_address for the firmware image + +static void print_help ( const char* ename ) +{ + printf ( "Firmware image packer and calculator for broadcom-based modems.\n" ); + printf ( "Part of bcm-utils package.\n" ); + printf ( "(c) 2009 Necromant (http://necromant.ath.cx). Thanks to Luke-jr for his initial work.\n" ); + printf ( "usage: %s [options]\n", ename ); + printf ( "Valid options are:\n" ); + printf ( "--magic_bytes=value \t- specify magic bytes at the beginning of the image. default - 3349\n" ); + printf ( "\t\t\t these can be sa2100 (for DPC2100 modem),\n\t\t\t sa3349 (haxorware guys use this one for some reason),\n\t\t\t or a custom hex value e.g. 0xFFFF\n" ); + printf ( "--compress \t\t - Make use of LZMA (weird!) compression (Doesn't work yet).\n" ); + printf ( "--rev_maj=value\t\t - major revision number. default 0\n" ); + printf ( "--rev_min=value\t\t - minor revision number default 0\n" ); + printf ( "--filename=value\t - use this filename in header instead of default (input filename)\n" ); + printf ( "--ldaddress=value\t - hex value of the target load address. defaults to 0x80010000\n" ); + printf ( "--input_file=value\t - What file are we packing?\n" ); + printf ( "--output_file=value\t - What file shall we write? (default: image.bin)\n" ); +#ifdef _HAX0RSTYLE + printf ( "--credz\t - Give some credz!\n" ); +#endif + printf ( "\n" ); +} + +static time_t source_date_epoch = -1; +static void set_source_date_epoch() { + char *env = getenv("SOURCE_DATE_EPOCH"); + char *endptr = env; + errno = 0; + if (env && *env) { + source_date_epoch = strtoull(env, &endptr, 10); + if (errno || (endptr && *endptr != '\0')) { + fprintf(stderr, "Invalid SOURCE_DATE_EPOCH"); + exit(1); + } + } +} + +int main ( int argc, char** argv ) +{ + if ( argc<2 ) + { + print_help ( argv[0] ); + } + + static struct option long_options[] = + { + {"magic_bytes", required_argument, 0, 'm'}, + {"rev_maj", required_argument, 0, 'j'}, + {"rev_min", required_argument, 0, 'n'}, + {"ldaddress", required_argument, 0, 'l'}, + {"filename", required_argument, 0, 'f'}, + {"input_file", required_argument, 0, 'i'}, + {"output_file", required_argument, 0, 'o'}, + {"compress", no_argument, &flag_compress, 'c'}, + {"version", no_argument, &flag_print_version, 'v'}, + {"help", no_argument, &flag_print_help, 'h'}, + {0, 0, 0, 0} + }; + int option_index = 0; + int opt_result=0; + char* filename=NULL; + char* input=NULL; + char* magic=NULL; + char* major=NULL; + char* minor=NULL; + char* ldaddr=NULL; + char* output=NULL; + + while ( opt_result>=0 ) + { + opt_result = getopt_long ( argc, argv, "m:j:n:f:i:o:vh", long_options, &option_index ); + switch ( opt_result ) + { + case 0: + printf ( "o!\n" ); + break; + case 'h': + print_help ( argv[0] ); + break; + case 'l': + ldaddr=optarg; + break; + case 'f': + filename=optarg; + break; + case 'i': + input=optarg; + break; + case 'o': + output=optarg; + break; + case 'm': + magic=optarg; + break; + case 'j': + major=optarg; + break; + case 'n': + minor=optarg; + break; + } + } + if ( input==NULL ) + { + printf ( "Telepaths are still on holidays. I guess you should tell me what file should I process.\n\n" ); + exit ( 1 ); + } + if ( access ( input,R_OK ) !=0 ) + { + printf ( "I cannot access the file %s. Is it there? Am I allowed?\n\n", input ); + exit ( 1 ); + } + uint32_t magicnum=sa2100_magic; + + if ( magic ) + { + if ( strcmp ( magic,"sa2100" ) ==0 ) magicnum=sa2100_magic; else + if ( strcmp ( magic,"sa3349" ) ==0 ) magicnum=sa3349_magic; else + { + sscanf ( magic, "0x%04X", &magicnum ); + } + } + unsigned int majrev=0; + if ( major ) + { + sscanf ( major, "%d", &majrev ); + } + unsigned int minrev=0; + if ( minor ) + { + sscanf ( minor, "%d", &minrev ); + } + uint32_t ldaddress = default_load_address; + if ( ldaddr ) + { + sscanf ( ldaddr, "0x%08X", &ldaddress ); + } + char* dupe = strdup(input); + char* fname = basename ( dupe ); + if ( filename ) + { + fname = filename; + } + + time_t t = -1; + set_source_date_epoch(); + if (source_date_epoch != -1) { + t = source_date_epoch; + } else if ((time(&t) == (time_t)(-1))) { + fprintf(stderr, "time call failed\n"); + return EXIT_FAILURE; + } + + struct stat buf; + stat ( input,&buf ); + ldr_header_t* head = construct_header ( magicnum, (uint16_t) majrev, (uint16_t) minrev, ( uint32_t ) t, ( uint32_t ) buf.st_size, ldaddress, fname, get_file_crc ( input ) ); + free(dupe); + //uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc + //FILE* fd = fopen ("/tftpboot/haxorware11rev32.bin","r"); + //fread(head,sizeof(ldr_header_t),1,fd); + char* filebuffer = malloc ( buf.st_size+10 ); + FILE* fd = fopen ( input,"r" ); + fread ( filebuffer, 1, buf.st_size,fd ); + if (!output) + { + output = malloc(strlen(input+5)); + strcpy(output,input); + strcat(output,".bin"); + } + dump_header ( head ); + FILE* fd_out = fopen ( output,"w+" ); + if (!fd_out) + { + fprintf(stderr, "Failed to open output file: %s\n", output); + exit(1); + } + fwrite ( head,1,sizeof ( ldr_header_t ),fd_out ); + fwrite ( filebuffer,1,buf.st_size,fd_out ); + printf("Firmware image %s is ready\n", output); + return 0; +} diff --git a/tools/firmware-utils/src/imagetag.c b/tools/firmware-utils/src/imagetag.c index bebaba2f29d..bc70399ccaa 100644 --- a/tools/firmware-utils/src/imagetag.c +++ b/tools/firmware-utils/src/imagetag.c @@ -11,13 +11,14 @@ #include <stdlib.h> #include <string.h> #include <stdint.h> -#include <time.h> #include <unistd.h> #include <sys/stat.h> #include <netinet/in.h> +#include <inttypes.h> #include "bcm_tag.h" #include "imagetag_cmdline.h" +#include "cyg_crc.h" #define DEADCODE 0xDEADC0DE @@ -30,54 +31,11 @@ struct kernelhdr { static char pirellitab[NUM_PIRELLI][BOARDID_LEN] = PIRELLI_BOARDS; -static uint32_t crc32tab[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - void int2tag(char *tag, uint32_t value) { uint32_t network = htonl(value); memcpy(tag, (char *)(&network), 4); } -uint32_t crc32(uint32_t crc, uint8_t *data, size_t len) -{ - while (len--) - crc = (crc >> 8) ^ crc32tab[(crc ^ *data++) & 0xFF]; - - return crc; -} - uint32_t compute_crc32(uint32_t crc, FILE *binfile, size_t compute_start, size_t compute_len) { uint8_t readbuf[1024]; @@ -88,14 +46,14 @@ uint32_t compute_crc32(uint32_t crc, FILE *binfile, size_t compute_start, size_t /* read block of 1024 bytes */ while (binfile && !feof(binfile) && !ferror(binfile) && (compute_len >= sizeof(readbuf))) { read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), binfile); - crc = crc32(crc, readbuf, read); + crc = cyg_crc32_accumulate(crc, readbuf, read); compute_len = compute_len - read; } /* Less than 1024 bytes remains, read compute_len bytes */ if (binfile && !feof(binfile) && !ferror(binfile) && (compute_len > 0)) { read = fread(readbuf, sizeof(uint8_t), compute_len, binfile); - crc = crc32(crc, readbuf, read); + crc = cyg_crc32_accumulate(crc, readbuf, read); } return crc; @@ -125,7 +83,8 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \ struct kernelhdr khdr; FILE *kernelfile = NULL, *rootfsfile = NULL, *binfile = NULL, *cfefile = NULL; size_t cfeoff, cfelen, kerneloff, kernellen, rootfsoff, rootfslen, \ - read, imagelen, rootfsoffpadlen = 0, kernelfslen, kerneloffpadlen = 0, oldrootfslen; + read, imagelen, rootfsoffpadlen = 0, kernelfslen, kerneloffpadlen = 0, oldrootfslen, \ + rootfsend; uint8_t readbuf[1024]; uint32_t imagecrc = IMAGETAG_CRC_START; uint32_t kernelcrc = IMAGETAG_CRC_START; @@ -199,11 +158,19 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \ kernellen += sizeof(khdr); } - /* Build the rootfs address and length (start and end do need to be aligned on flash erase block boundaries */ + /* Build the rootfs address and length */ rootfsoff = kerneloff + kernellen; - rootfsoff = (rootfsoff % block_size) > 0 ? (((rootfsoff / block_size) + 1) * block_size) : rootfsoff; - rootfslen = getlen(rootfsfile); - rootfslen = ( (rootfslen % block_size) > 0 ? (((rootfslen / block_size) + 1) * block_size) : rootfslen ); + /* align the start if requested */ + if (args->align_rootfs_flag) + rootfsoff = (rootfsoff % block_size) > 0 ? (((rootfsoff / block_size) + 1) * block_size) : rootfsoff; + else + rootfsoff = (rootfsoff % 4) > 0 ? (((rootfsoff / 4) + 1) * 4) : rootfsoff; + + /* align the end */ + rootfsend = rootfsoff + getlen(rootfsfile); + if ((rootfsend % block_size) > 0) + rootfsend = (((rootfsend / block_size) + 1) * block_size); + rootfslen = rootfsend - rootfsoff; imagelen = rootfsoff + rootfslen - kerneloff + sizeof(deadcode); rootfsoffpadlen = rootfsoff - (kerneloff + kernellen); @@ -231,6 +198,19 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \ fseek(binfile, rootfsoff + rootfslen - fwaddr + cfelen, SEEK_SET); fwrite(&deadcode, sizeof(uint32_t), 1, binfile); + oldrootfslen = rootfslen; + if (args->pad_given) { + uint32_t allfs = 0xffffffff; + uint32_t pad_size = args->pad_arg * 1024 * 1024; + + printf("Padding image to %d bytes ...\n", pad_size); + while (imagelen < pad_size) { + fwrite(&allfs, sizeof(uint32_t), 1, binfile); + imagelen += 4; + rootfslen += 4; + } + } + /* Flush the binfile buffer so that when we read from file, it contains * everything in the buffer */ @@ -260,6 +240,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \ rootfslen = oldrootfslen; rootfslen = ( (rootfslen % block_size) > 0 ? (((rootfslen / block_size) + 1) * block_size) : rootfslen ); kerneloffpadlen = rootfslen - oldrootfslen; + oldrootfslen = rootfslen; kerneloff = rootfsoff + rootfslen; kernellen = getlen(kernelfile); @@ -325,7 +306,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \ sprintf(tag.totalLength, "%lu", imagelen); if (args->cfe_given) { - sprintf(tag.cfeAddress, "%lu", flash_start); + sprintf(tag.cfeAddress, "%" PRIu32, flash_start); sprintf(tag.cfeLength, "%lu", cfelen); } else { /* We don't include CFE */ @@ -343,7 +324,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \ sprintf(tag.flashImageStart, "%lu", kerneloff); sprintf(tag.flashRootLength, "%lu", rootfslen + sizeof(deadcode)); } - int2tag(tag.rootLength, rootfslen + sizeof(deadcode)); + int2tag(tag.rootLength, oldrootfslen + sizeof(deadcode)); if (args->rsa_signature_given) { strncpy(tag.rsa_signature, args->rsa_signature_arg, RSASIG_LEN); @@ -366,7 +347,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \ } if (args->altinfo_given) { - strncpy(&tag.information1[0], args->altinfo_arg, ALTTAGINFO_LEN); + strncpy(tag.information1, args->altinfo_arg, TAGINFO1_LEN); } if (args->second_image_flag_given) { @@ -397,7 +378,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \ int2tag(&(tag.rootfsCRC[0]), rootfscrc); int2tag(tag.kernelCRC, kernelcrc); int2tag(tag.fskernelCRC, kernelfscrc); - int2tag(tag.headerCRC, crc32(IMAGETAG_CRC_START, (uint8_t*)&tag, sizeof(tag) - 20)); + int2tag(tag.headerCRC, cyg_crc32_accumulate(IMAGETAG_CRC_START, (uint8_t*)&tag, sizeof(tag) - 20)); fseek(binfile, 0L, SEEK_SET); fwrite(&tag, sizeof(uint8_t), sizeof(tag), binfile); @@ -418,7 +399,7 @@ int main(int argc, char **argv) kernel = rootfs = bin = NULL; - if (cmdline_parser(argc, argv, &parsed_args)) { + if (imagetag_cmdline(argc, argv, &parsed_args)) { exit(1); } @@ -483,6 +464,14 @@ int main(int argc, char **argv) exit(1); } } + + if (parsed_args.pad_given) { + if (parsed_args.pad_arg < 0) { + fprintf(stderr, "Error: pad size must be positive.\r"); + exit(1); + } + } + flash_start = strtoul(parsed_args.flash_start_arg, NULL, 16); image_offset = strtoul(parsed_args.image_offset_arg, NULL, 16); block_size = strtoul(parsed_args.block_size_arg, NULL, 16); diff --git a/tools/firmware-utils/src/imagetag.ggo b/tools/firmware-utils/src/imagetag.ggo index 7e8e7d90e32..73184852935 100644 --- a/tools/firmware-utils/src/imagetag.ggo +++ b/tools/firmware-utils/src/imagetag.ggo @@ -42,3 +42,5 @@ option "second-image-flag" - "Dual Image Flag (2=not-specified)." values="0", "1 option "inactive" - "Inactive Flag (2=not-specified)." values="0", "1", "2" default="2" typestr="flag-value" optional option "reserved2" - "String for second reserved section." string optional option "kernel-file-has-header" - "Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed" flag off +option "pad" p "Pad the image to this size if smaller (in MiB)" int typestr="size (in MiB)" optional +option "align-rootfs" - "Align the rootfs start to erase block size" flag off diff --git a/tools/firmware-utils/src/imagetag_cmdline.c b/tools/firmware-utils/src/imagetag_cmdline.c index 91ac90b09d0..86c90bbb678 100644 --- a/tools/firmware-utils/src/imagetag_cmdline.c +++ b/tools/firmware-utils/src/imagetag_cmdline.c @@ -1,7 +1,7 @@ /* - File autogenerated by gengetopt version 2.22.4 + File autogenerated by gengetopt version 2.22.5 generated with the following command: - gengetopt --file-name=imagetag_cmdline --file-name=imagetag_cmdline + gengetopt -i imagetag.ggo -f imagetag_cmdline --file-name=imagetag_cmdline The developers of gengetopt consider the fixed text that goes in all gengetopt output files to be in the public domain: @@ -58,13 +58,16 @@ const char *gengetopt_args_info_help[] = { " --inactive=flag-value Inactive Flag (2=not-specified). (possible \n values=\"0\", \"1\", \"2\" default=`2')", " --reserved2=STRING String for second reserved section.", " --kernel-file-has-header Indicates that the kernel file includes the \n kernel header with correct load address and \n entry point, so no changes are needed \n (default=off)", + " -p, --pad=size (in MiB) Pad the image to this size if smaller (in MiB)", + " --align-rootfs Align the rootfs start to erase block size \n (default=off)", 0 }; typedef enum {ARG_NO , ARG_FLAG , ARG_STRING -} cmdline_parser_arg_type; + , ARG_INT +} imagetag_cmdline_arg_type; static void clear_given (struct gengetopt_args_info *args_info); @@ -72,14 +75,14 @@ static void clear_args (struct gengetopt_args_info *args_info); static int -cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params, const char *additional_error); +imagetag_cmdline_internal (int argc, char **argv, struct gengetopt_args_info *args_info, + struct imagetag_cmdline_params *params, const char *additional_error); static int -cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error); +imagetag_cmdline_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error); -const char *cmdline_parser_second_image_flag_values[] = {"0", "1", "2", 0}; /*< Possible values for second-image-flag. */ -const char *cmdline_parser_inactive_values[] = {"0", "1", "2", 0}; /*< Possible values for inactive. */ +const char *imagetag_cmdline_second_image_flag_values[] = {"0", "1", "2", 0}; /*< Possible values for second-image-flag. */ +const char *imagetag_cmdline_inactive_values[] = {"0", "1", "2", 0}; /*< Possible values for inactive. */ static char * gengetopt_strdup (const char *s); @@ -113,6 +116,8 @@ void clear_given (struct gengetopt_args_info *args_info) args_info->inactive_given = 0 ; args_info->reserved2_given = 0 ; args_info->kernel_file_has_header_given = 0 ; + args_info->pad_given = 0 ; + args_info->align_rootfs_given = 0 ; } static @@ -165,6 +170,8 @@ void clear_args (struct gengetopt_args_info *args_info) args_info->reserved2_arg = NULL; args_info->reserved2_orig = NULL; args_info->kernel_file_has_header_flag = 0; + args_info->pad_orig = NULL; + args_info->align_rootfs_flag = 0; } @@ -199,19 +206,21 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->inactive_help = gengetopt_args_info_help[23] ; args_info->reserved2_help = gengetopt_args_info_help[24] ; args_info->kernel_file_has_header_help = gengetopt_args_info_help[25] ; + args_info->pad_help = gengetopt_args_info_help[26] ; + args_info->align_rootfs_help = gengetopt_args_info_help[27] ; } void -cmdline_parser_print_version (void) +imagetag_cmdline_print_version (void) { printf ("%s %s\n", - (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), - CMDLINE_PARSER_VERSION); + (strlen(IMAGETAG_CMDLINE_PACKAGE_NAME) ? IMAGETAG_CMDLINE_PACKAGE_NAME : IMAGETAG_CMDLINE_PACKAGE), + IMAGETAG_CMDLINE_VERSION); } static void print_help_common(void) { - cmdline_parser_print_version (); + imagetag_cmdline_print_version (); if (strlen(gengetopt_args_info_purpose) > 0) printf("\n%s\n", gengetopt_args_info_purpose); @@ -226,7 +235,7 @@ static void print_help_common(void) { } void -cmdline_parser_print_help (void) +imagetag_cmdline_print_help (void) { int i = 0; print_help_common(); @@ -235,7 +244,7 @@ cmdline_parser_print_help (void) } void -cmdline_parser_init (struct gengetopt_args_info *args_info) +imagetag_cmdline_init (struct gengetopt_args_info *args_info) { clear_given (args_info); clear_args (args_info); @@ -243,7 +252,7 @@ cmdline_parser_init (struct gengetopt_args_info *args_info) } void -cmdline_parser_params_init(struct cmdline_parser_params *params) +imagetag_cmdline_params_init(struct imagetag_cmdline_params *params) { if (params) { @@ -255,12 +264,12 @@ cmdline_parser_params_init(struct cmdline_parser_params *params) } } -struct cmdline_parser_params * -cmdline_parser_params_create(void) +struct imagetag_cmdline_params * +imagetag_cmdline_params_create(void) { - struct cmdline_parser_params *params = - (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); - cmdline_parser_params_init(params); + struct imagetag_cmdline_params *params = + (struct imagetag_cmdline_params *)malloc(sizeof(struct imagetag_cmdline_params)); + imagetag_cmdline_params_init(params); return params; } @@ -276,7 +285,7 @@ free_string_field (char **s) static void -cmdline_parser_release (struct gengetopt_args_info *args_info) +imagetag_cmdline_release (struct gengetopt_args_info *args_info) { free_string_field (&(args_info->kernel_arg)); @@ -323,6 +332,7 @@ cmdline_parser_release (struct gengetopt_args_info *args_info) free_string_field (&(args_info->inactive_orig)); free_string_field (&(args_info->reserved2_arg)); free_string_field (&(args_info->reserved2_orig)); + free_string_field (&(args_info->pad_orig)); @@ -384,13 +394,13 @@ write_into_file(FILE *outfile, const char *opt, const char *arg, const char *val int -cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) +imagetag_cmdline_dump(FILE *outfile, struct gengetopt_args_info *args_info) { int i = 0; if (!outfile) { - fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); + fprintf (stderr, "%s: cannot dump options to stream\n", IMAGETAG_CMDLINE_PACKAGE); return EXIT_FAILURE; } @@ -439,13 +449,17 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) if (args_info->rsa_signature_given) write_into_file(outfile, "rsa-signature", args_info->rsa_signature_orig, 0); if (args_info->second_image_flag_given) - write_into_file(outfile, "second-image-flag", args_info->second_image_flag_orig, cmdline_parser_second_image_flag_values); + write_into_file(outfile, "second-image-flag", args_info->second_image_flag_orig, imagetag_cmdline_second_image_flag_values); if (args_info->inactive_given) - write_into_file(outfile, "inactive", args_info->inactive_orig, cmdline_parser_inactive_values); + write_into_file(outfile, "inactive", args_info->inactive_orig, imagetag_cmdline_inactive_values); if (args_info->reserved2_given) write_into_file(outfile, "reserved2", args_info->reserved2_orig, 0); if (args_info->kernel_file_has_header_given) write_into_file(outfile, "kernel-file-has-header", 0, 0 ); + if (args_info->pad_given) + write_into_file(outfile, "pad", args_info->pad_orig, 0); + if (args_info->align_rootfs_given) + write_into_file(outfile, "align-rootfs", 0, 0 ); i = EXIT_SUCCESS; @@ -453,7 +467,7 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) } int -cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) +imagetag_cmdline_file_save(const char *filename, struct gengetopt_args_info *args_info) { FILE *outfile; int i = 0; @@ -462,20 +476,20 @@ cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_ if (!outfile) { - fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); + fprintf (stderr, "%s: cannot open file for writing: %s\n", IMAGETAG_CMDLINE_PACKAGE, filename); return EXIT_FAILURE; } - i = cmdline_parser_dump(outfile, args_info); + i = imagetag_cmdline_dump(outfile, args_info); fclose (outfile); return i; } void -cmdline_parser_free (struct gengetopt_args_info *args_info) +imagetag_cmdline_free (struct gengetopt_args_info *args_info) { - cmdline_parser_release (args_info); + imagetag_cmdline_release (args_info); } /** @brief replacement of strdup, which is not standard */ @@ -494,21 +508,21 @@ gengetopt_strdup (const char *s) } int -cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) +imagetag_cmdline (int argc, char **argv, struct gengetopt_args_info *args_info) { - return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); + return imagetag_cmdline2 (argc, argv, args_info, 0, 1, 1); } int -cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params) +imagetag_cmdline_ext (int argc, char **argv, struct gengetopt_args_info *args_info, + struct imagetag_cmdline_params *params) { int result; - result = cmdline_parser_internal (argc, argv, args_info, params, 0); + result = imagetag_cmdline_internal (argc, argv, args_info, params, 0); if (result == EXIT_FAILURE) { - cmdline_parser_free (args_info); + imagetag_cmdline_free (args_info); exit (EXIT_FAILURE); } @@ -516,10 +530,10 @@ cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info } int -cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +imagetag_cmdline2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) { int result; - struct cmdline_parser_params params; + struct imagetag_cmdline_params params; params.override = override; params.initialize = initialize; @@ -527,11 +541,11 @@ cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, i params.check_ambiguity = 0; params.print_errors = 1; - result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); + result = imagetag_cmdline_internal (argc, argv, args_info, ¶ms, 0); if (result == EXIT_FAILURE) { - cmdline_parser_free (args_info); + imagetag_cmdline_free (args_info); exit (EXIT_FAILURE); } @@ -539,16 +553,16 @@ cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, i } int -cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) +imagetag_cmdline_required (struct gengetopt_args_info *args_info, const char *prog_name) { int result = EXIT_SUCCESS; - if (cmdline_parser_required2(args_info, prog_name, 0) > 0) + if (imagetag_cmdline_required2(args_info, prog_name, 0) > 0) result = EXIT_FAILURE; if (result == EXIT_FAILURE) { - cmdline_parser_free (args_info); + imagetag_cmdline_free (args_info); exit (EXIT_FAILURE); } @@ -556,7 +570,7 @@ cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog } int -cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error) +imagetag_cmdline_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error) { int error = 0; FIX_UNUSED (additional_error); @@ -623,8 +637,8 @@ static char *package_name = 0; * @param possible_values the possible values for this option (if specified) * @param default_value the default value (in case the option only accepts fixed values) * @param arg_type the type of this option - * @param check_ambiguity @see cmdline_parser_params.check_ambiguity - * @param override @see cmdline_parser_params.override + * @param check_ambiguity @see imagetag_cmdline_params.check_ambiguity + * @param override @see imagetag_cmdline_params.override * @param no_free whether to free a possible previous value * @param multiple_option whether this is a multiple option * @param long_opt the corresponding long option @@ -636,7 +650,7 @@ int update_arg(void *field, char **orig_field, unsigned int *field_given, unsigned int *prev_given, char *value, const char *possible_values[], const char *default_value, - cmdline_parser_arg_type arg_type, + imagetag_cmdline_arg_type arg_type, int check_ambiguity, int override, int no_free, int multiple_option, const char *long_opt, char short_opt, @@ -690,6 +704,9 @@ int update_arg(void *field, char **orig_field, case ARG_FLAG: *((int *)field) = !*((int *)field); break; + case ARG_INT: + if (val) *((int *)field) = strtol (val, &stop_char, 0); + break; case ARG_STRING: if (val) { string_field = (char **)field; @@ -702,6 +719,17 @@ int update_arg(void *field, char **orig_field, break; }; + /* check numeric conversion */ + switch(arg_type) { + case ARG_INT: + if (val && !(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); + return 1; /* failure */ + } + break; + default: + ; + }; /* store the original value */ switch(arg_type) { @@ -725,9 +753,9 @@ int update_arg(void *field, char **orig_field, int -cmdline_parser_internal ( +imagetag_cmdline_internal ( int argc, char **argv, struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params, const char *additional_error) + struct imagetag_cmdline_params *params, const char *additional_error) { int c; /* Character of the parsed option. */ @@ -747,9 +775,9 @@ cmdline_parser_internal ( check_ambiguity = params->check_ambiguity; if (initialize) - cmdline_parser_init (args_info); + imagetag_cmdline_init (args_info); - cmdline_parser_init (&local_args_info); + imagetag_cmdline_init (&local_args_info); optarg = 0; optind = 0; @@ -787,23 +815,25 @@ cmdline_parser_internal ( { "inactive", 1, NULL, 0 }, { "reserved2", 1, NULL, 0 }, { "kernel-file-has-header", 0, NULL, 0 }, + { "pad", 1, NULL, 'p' }, + { "align-rootfs", 0, NULL, 0 }, { 0, 0, 0, 0 } }; - c = getopt_long (argc, argv, "hVi:f:o:b:c:s:n:v:a:m:k:l:e:y:1:2:r:", long_options, &option_index); + c = getopt_long (argc, argv, "hVi:f:o:b:c:s:n:v:a:m:k:l:e:y:1:2:r:p:", long_options, &option_index); if (c == -1) break; /* Exit from `while (1)' loop. */ switch (c) { case 'h': /* Print help and exit. */ - cmdline_parser_print_help (); - cmdline_parser_free (&local_args_info); + imagetag_cmdline_print_help (); + imagetag_cmdline_free (&local_args_info); exit (EXIT_SUCCESS); case 'V': /* Print version and exit. */ - cmdline_parser_print_version (); - cmdline_parser_free (&local_args_info); + imagetag_cmdline_print_version (); + imagetag_cmdline_free (&local_args_info); exit (EXIT_SUCCESS); case 'i': /* File with LZMA compressed kernel to include in the image.. */ @@ -1010,6 +1040,18 @@ cmdline_parser_internal ( goto failure; break; + case 'p': /* Pad the image to this size if smaller (in MiB). */ + + + if (update_arg( (void *)&(args_info->pad_arg), + &(args_info->pad_orig), &(args_info->pad_given), + &(local_args_info.pad_given), optarg, 0, 0, ARG_INT, + check_ambiguity, override, 0, 0, + "pad", 'p', + additional_error)) + goto failure; + + break; case 0: /* Long option with no short option */ /* File with CFE to include in the image.. */ @@ -1059,7 +1101,7 @@ cmdline_parser_internal ( if (update_arg( (void *)&(args_info->second_image_flag_arg), &(args_info->second_image_flag_orig), &(args_info->second_image_flag_given), - &(local_args_info.second_image_flag_given), optarg, cmdline_parser_second_image_flag_values, "2", ARG_STRING, + &(local_args_info.second_image_flag_given), optarg, imagetag_cmdline_second_image_flag_values, "2", ARG_STRING, check_ambiguity, override, 0, 0, "second-image-flag", '-', additional_error)) @@ -1073,7 +1115,7 @@ cmdline_parser_internal ( if (update_arg( (void *)&(args_info->inactive_arg), &(args_info->inactive_orig), &(args_info->inactive_given), - &(local_args_info.inactive_given), optarg, cmdline_parser_inactive_values, "2", ARG_STRING, + &(local_args_info.inactive_given), optarg, imagetag_cmdline_inactive_values, "2", ARG_STRING, check_ambiguity, override, 0, 0, "inactive", '-', additional_error)) @@ -1106,6 +1148,18 @@ cmdline_parser_internal ( goto failure; } + /* Align the rootfs start to erase block size. */ + else if (strcmp (long_options[option_index].name, "align-rootfs") == 0) + { + + + if (update_arg((void *)&(args_info->align_rootfs_flag), 0, &(args_info->align_rootfs_given), + &(local_args_info.align_rootfs_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "align-rootfs", '-', + additional_error)) + goto failure; + + } break; case '?': /* Invalid option. */ @@ -1113,7 +1167,7 @@ cmdline_parser_internal ( goto failure; default: /* bug: option not considered. */ - fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); + fprintf (stderr, "%s: option unknown: %c%s\n", IMAGETAG_CMDLINE_PACKAGE, c, (additional_error ? additional_error : "")); abort (); } /* switch */ } /* while */ @@ -1122,10 +1176,10 @@ cmdline_parser_internal ( if (check_required) { - error += cmdline_parser_required2 (args_info, argv[0], additional_error); + error += imagetag_cmdline_required2 (args_info, argv[0], additional_error); } - cmdline_parser_release (&local_args_info); + imagetag_cmdline_release (&local_args_info); if ( error ) return (EXIT_FAILURE); @@ -1134,6 +1188,6 @@ cmdline_parser_internal ( failure: - cmdline_parser_release (&local_args_info); + imagetag_cmdline_release (&local_args_info); return (EXIT_FAILURE); } diff --git a/tools/firmware-utils/src/imagetag_cmdline.h b/tools/firmware-utils/src/imagetag_cmdline.h index c566a9f2932..3f55c509bb3 100644 --- a/tools/firmware-utils/src/imagetag_cmdline.h +++ b/tools/firmware-utils/src/imagetag_cmdline.h @@ -1,6 +1,6 @@ /** @file imagetag_cmdline.h * @brief The header file for the command line option parser - * generated by GNU Gengetopt version 2.22.4 + * generated by GNU Gengetopt version 2.22.5 * http://www.gnu.org/software/gengetopt. * DO NOT modify this file, since it can be overwritten * @author GNU Gengetopt by Lorenzo Bettini */ @@ -19,19 +19,19 @@ extern "C" { #endif /* __cplusplus */ -#ifndef CMDLINE_PARSER_PACKAGE +#ifndef IMAGETAG_CMDLINE_PACKAGE /** @brief the program name (used for printing errors) */ -#define CMDLINE_PARSER_PACKAGE "imagetag" +#define IMAGETAG_CMDLINE_PACKAGE "imagetag" #endif -#ifndef CMDLINE_PARSER_PACKAGE_NAME +#ifndef IMAGETAG_CMDLINE_PACKAGE_NAME /** @brief the complete program name (used for help and version) */ -#define CMDLINE_PARSER_PACKAGE_NAME "imagetag" +#define IMAGETAG_CMDLINE_PACKAGE_NAME "imagetag" #endif -#ifndef CMDLINE_PARSER_VERSION +#ifndef IMAGETAG_CMDLINE_VERSION /** @brief the program version */ -#define CMDLINE_PARSER_VERSION "2.0.0" +#define IMAGETAG_CMDLINE_VERSION "2.0.0" #endif /** @brief Where the command line options are stored */ @@ -109,6 +109,11 @@ struct gengetopt_args_info const char *reserved2_help; /**< @brief String for second reserved section. help description. */ int kernel_file_has_header_flag; /**< @brief Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed (default=off). */ const char *kernel_file_has_header_help; /**< @brief Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed help description. */ + int pad_arg; /**< @brief Pad the image to this size if smaller (in MiB). */ + char * pad_orig; /**< @brief Pad the image to this size if smaller (in MiB) original value given at command line. */ + const char *pad_help; /**< @brief Pad the image to this size if smaller (in MiB) help description. */ + int align_rootfs_flag; /**< @brief Align the rootfs start to erase block size (default=off). */ + const char *align_rootfs_help; /**< @brief Align the rootfs start to erase block size help description. */ unsigned int help_given ; /**< @brief Whether help was given. */ unsigned int version_given ; /**< @brief Whether version was given. */ @@ -136,11 +141,13 @@ struct gengetopt_args_info unsigned int inactive_given ; /**< @brief Whether inactive was given. */ unsigned int reserved2_given ; /**< @brief Whether reserved2 was given. */ unsigned int kernel_file_has_header_given ; /**< @brief Whether kernel-file-has-header was given. */ + unsigned int pad_given ; /**< @brief Whether pad was given. */ + unsigned int align_rootfs_given ; /**< @brief Whether align-rootfs was given. */ } ; /** @brief The additional parameters to pass to parser functions */ -struct cmdline_parser_params +struct imagetag_cmdline_params { int override; /**< @brief whether to override possibly already present options (default 0) */ int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ @@ -163,7 +170,7 @@ extern const char *gengetopt_args_info_help[]; * @param args_info the structure where option information will be stored * @return 0 if everything went fine, NON 0 if an error took place */ -int cmdline_parser (int argc, char **argv, +int imagetag_cmdline (int argc, char **argv, struct gengetopt_args_info *args_info); /** @@ -175,9 +182,9 @@ int cmdline_parser (int argc, char **argv, * @param initialize whether to initialize the option structure my_args_info * @param check_required whether to check that all required options were provided * @return 0 if everything went fine, NON 0 if an error took place - * @deprecated use cmdline_parser_ext() instead + * @deprecated use imagetag_cmdline_ext() instead */ -int cmdline_parser2 (int argc, char **argv, +int imagetag_cmdline2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required); @@ -189,9 +196,9 @@ int cmdline_parser2 (int argc, char **argv, * @param params additional parameters for the parser * @return 0 if everything went fine, NON 0 if an error took place */ -int cmdline_parser_ext (int argc, char **argv, +int imagetag_cmdline_ext (int argc, char **argv, struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params); + struct imagetag_cmdline_params *params); /** * Save the contents of the option struct into an already open FILE stream. @@ -199,7 +206,7 @@ int cmdline_parser_ext (int argc, char **argv, * @param args_info the option struct to dump * @return 0 if everything went fine, NON 0 if an error took place */ -int cmdline_parser_dump(FILE *outfile, +int imagetag_cmdline_dump(FILE *outfile, struct gengetopt_args_info *args_info); /** @@ -209,44 +216,44 @@ int cmdline_parser_dump(FILE *outfile, * @param args_info the option struct to save * @return 0 if everything went fine, NON 0 if an error took place */ -int cmdline_parser_file_save(const char *filename, +int imagetag_cmdline_file_save(const char *filename, struct gengetopt_args_info *args_info); /** * Print the help */ -void cmdline_parser_print_help(void); +void imagetag_cmdline_print_help(void); /** * Print the version */ -void cmdline_parser_print_version(void); +void imagetag_cmdline_print_version(void); /** - * Initializes all the fields a cmdline_parser_params structure + * Initializes all the fields a imagetag_cmdline_params structure * to their default values * @param params the structure to initialize */ -void cmdline_parser_params_init(struct cmdline_parser_params *params); +void imagetag_cmdline_params_init(struct imagetag_cmdline_params *params); /** - * Allocates dynamically a cmdline_parser_params structure and initializes + * Allocates dynamically a imagetag_cmdline_params structure and initializes * all its fields to their default values - * @return the created and initialized cmdline_parser_params structure + * @return the created and initialized imagetag_cmdline_params structure */ -struct cmdline_parser_params *cmdline_parser_params_create(void); +struct imagetag_cmdline_params *imagetag_cmdline_params_create(void); /** * Initializes the passed gengetopt_args_info structure's fields * (also set default values for options that have a default) * @param args_info the structure to initialize */ -void cmdline_parser_init (struct gengetopt_args_info *args_info); +void imagetag_cmdline_init (struct gengetopt_args_info *args_info); /** * Deallocates the string fields of the gengetopt_args_info structure * (but does not deallocate the structure itself) * @param args_info the structure to deallocate */ -void cmdline_parser_free (struct gengetopt_args_info *args_info); +void imagetag_cmdline_free (struct gengetopt_args_info *args_info); /** * Checks that all the required options were specified @@ -255,11 +262,11 @@ void cmdline_parser_free (struct gengetopt_args_info *args_info); * possible errors * @return */ -int cmdline_parser_required (struct gengetopt_args_info *args_info, +int imagetag_cmdline_required (struct gengetopt_args_info *args_info, const char *prog_name); -extern const char *cmdline_parser_second_image_flag_values[]; /**< @brief Possible values for second-image-flag. */ -extern const char *cmdline_parser_inactive_values[]; /**< @brief Possible values for inactive. */ +extern const char *imagetag_cmdline_second_image_flag_values[]; /**< @brief Possible values for second-image-flag. */ +extern const char *imagetag_cmdline_inactive_values[]; /**< @brief Possible values for inactive. */ #ifdef __cplusplus diff --git a/tools/firmware-utils/src/jcgimage.c b/tools/firmware-utils/src/jcgimage.c new file mode 100644 index 00000000000..354c26be19b --- /dev/null +++ b/tools/firmware-utils/src/jcgimage.c @@ -0,0 +1,425 @@ +/* + * jcgimage - Create a JCG firmware image + * + * Copyright (C) 2015 Reinhard Max <reinhard@m4x.de> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/* + * JCG firmware update images consist of a 512 byte header and a + * modified uImage (details below) as the payload. + * + * The payload is obfuscated by XORing it with a key that is generated + * from parts of the header. Fortunately only non-essential parts of + * the header are used for this and zeroing them results in a zero + * key, effectively disabling the obfuscation and allowing us to use + * clear text payloads. + * + * The mandatory parts of the header are: + * + * - A magic string of "YSZJ" at offset 0. + * - A value of 1 at offset 39 (header format version?) + * - A CRC32 checksum of the payload at offset 504. + * - A CRC32 checksum of the header at offset 508. + * + * An image constructed by these rules will be accepted by JCG's + * U-Boot in resuce mode via TFTP and the payload will be written to + * the flash starting at offset 0x00050000. + * + * JCG's U-Boot does check the content or size of the payload + * image. If it is too large, it wraps around and overwrites U-Boot, + * requiring JTAG to revive the board. To prevent such bricking from + * happening, this tool refuses to build such overlong images. + * + * Two more conditions have to be met for a JCG image to be accepted + * as a valid update by the web interface of the stock firware: + * + * - The bytes at offsets 109 and 111 in the header must be a binary + * representation of the first two components of the firmware + * version as displayed in the update web form, or it will be + * rejected as "incorrect product". + * + * - The payload must start with a valid uImage header whose data + * CRC checksum matches the whole rest of the update file rather + * than just the number of bytes specified in the size field of the + * header. + * + * This last condition is met by JCG's original firmware images, + * because they have both, kernel and rootfs inside the uImage and + * abuse the last four bytes of the name field to record the offset of + * the file system from the start of the uImage header. This tool + * produces such images when called with -k and -r, which are meant to + * repack the original firmware after modifying the file systen, + * e.g. to add debugging tools and enable shell access. + * + * In contrast, OpenWrt sysupgrade images consist of a uImage that + * only contains the kernel and has the rootfs appended to it. Hence, + * the CRC over kernel and file system does not match the one in the + * uImage header. Fixing this by adjusting the uImage header is not + * possible, because it makes the uImage unusable for booting. Instead + * we append four "patch" bytes to the end of the file system, that + * are calculated to force the checksum of kernel+fs to be the same as + * for the kernel alone. + * + */ + +#include <zlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <libgen.h> +#include <stdlib.h> +#include <errno.h> +#include <err.h> +#include <time.h> +#include <sys/mman.h> +#include <arpa/inet.h> +#include <assert.h> + +/* + * JCG Firmware image header + */ +#define JH_MAGIC 0x59535a4a /* "YSZJ" */ +struct jcg_header { + uint32_t jh_magic; + uint8_t jh_version[32]; /* Firmware version string. + Fill with zeros to avoid encryption */ + uint32_t jh_type; /* must be 1 */ + uint8_t jh_info[64]; /* Firmware info string. Fill with + zeros to avoid encryption */ + uint32_t jh_time; /* Image creation time in seconds since + * the Epoch. Does not seem to be used + * by the stock firmware. */ + uint16_t jh_major; /* Major fimware version */ + uint16_t jh_minor; /* Minor fimrmware version */ + uint8_t jh_unknown[392]; /* Apparently unused and all zeros */ + uint32_t jh_dcrc; /* CRC checksum of the payload */ + uint32_t jh_hcrc; /* CRC checksum of the header */ +}; + +/* + * JCG uses a modified uImage header that replaces the last four bytes + * of the image name with the length of the kernel in the image. + */ +#define IH_MAGIC 0x27051956 /* Image Magic Number */ +#define IH_NMLEN 28 /* Image Name Length */ + +struct uimage_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + uint8_t ih_name[IH_NMLEN];/* Image Name */ + uint32_t ih_fsoff; /* Offset of the file system + partition from the start of + the header */ +}; + +/* + * Open the named file and return its size and file descriptor. + * Exit in case of errors. + */ +int +opensize(char *name, size_t *size) +{ + struct stat s; + int fd = open(name, O_RDONLY); + if (fd < 0) { + err(1, "cannot open \"%s\"", name); + } + if (fstat(fd, &s) == -1) { + err(1, "cannot stat \"%s\"", name); + } + *size = s.st_size; + return fd; +} + +static time_t source_date_epoch = -1; +static void set_source_date_epoch() { + char *env = getenv("SOURCE_DATE_EPOCH"); + char *endptr = env; + errno = 0; + if (env && *env) { + source_date_epoch = strtoull(env, &endptr, 10); + if (errno || (endptr && *endptr != '\0')) { + fprintf(stderr, "Invalid SOURCE_DATE_EPOCH"); + exit(1); + } + } +} + +/* + * Write the JCG header + */ +void +mkjcgheader(struct jcg_header *h, size_t psize, char *version) +{ + uLong crc; + uint16_t major = 0, minor = 0; + void *payload = (void *)h + sizeof(*h); + time_t t; + + if (source_date_epoch != -1) { + t = source_date_epoch; + } else if ((time(&t) == (time_t)(-1))) { + err(1, "time call failed"); + } + + if (version != NULL) { + if (sscanf(version, "%hu.%hu", &major, &minor) != 2) { + err(1, "cannot parse version \"%s\"", version); + } + } + + memset(h, 0, sizeof(*h)); + h->jh_magic = htonl(JH_MAGIC); + h->jh_type = htonl(1); + h->jh_time = htonl(t); + h->jh_major = htons(major); + h->jh_minor = htons(minor); + + /* CRC over JCG payload (uImage) */ + crc = crc32(0L, Z_NULL, 0); + crc = crc32(crc, payload, psize); + h->jh_dcrc = htonl(crc); + + /* CRC over JCG header */ + crc = crc32(0L, Z_NULL, 0); + crc = crc32(crc, (void *)h, sizeof(*h)); + h->jh_hcrc = htonl(crc); +} + +/* + * Write the uImage header + */ +void +mkuheader(struct uimage_header *h, size_t ksize, size_t fsize) +{ + uLong crc; + void *payload = (void *)h + sizeof(*h); + + // printf("mkuheader: %p, %zd, %zd\n", h, ksize, fsize); + memset(h, 0, sizeof(*h)); + h->ih_magic = htonl(IH_MAGIC); + h->ih_time = htonl(time(NULL)); + h->ih_size = htonl(ksize + fsize); + h->ih_load = htonl(0x80000000); + h->ih_ep = htonl(0x80292000); + h->ih_os = 0x05; + h->ih_arch = 0x05; + h->ih_type = 0x02; + h->ih_comp = 0x03; + h->ih_fsoff = htonl(sizeof(*h) + ksize); + strcpy((char *)h->ih_name, "Linux Kernel Image"); + + /* CRC over uImage payload (kernel and file system) */ + crc = crc32(0L, Z_NULL, 0); + crc = crc32(crc, payload, ntohl(h->ih_size)); + h->ih_dcrc = htonl(crc); + printf("CRC1: %08lx\n", crc); + + /* CRC over uImage header */ + crc = crc32(0L, Z_NULL, 0); + crc = crc32(crc, (void *)h, sizeof(*h)); + h->ih_hcrc = htonl(crc); + printf("CRC2: %08lx\n", crc); +} + +/* + * Calculate a "patch" value and write it into the last four bytes of + * buf, so that the CRC32 checksum of the whole buffer is dcrc. + * + * Based on: SAR-PR-2006-05: Reversing CRC – Theory and Practice. + * Martin Stigge, Henryk Plötz, Wolf Müller, Jens-Peter Redlich. + * http://sar.informatik.hu-berlin.de/research/publications/#SAR-PR-2006-05 + */ +void +craftcrc(uint32_t dcrc, uint8_t *buf, size_t len) +{ + int i; + uint32_t a; + uint32_t patch = 0; + uint32_t crc = crc32(0L, Z_NULL, 0); + + a = ~dcrc; + for (i = 0; i < 32; i++) { + if (patch & 1) { + patch = (patch >> 1) ^ 0xedb88320L; + } else { + patch >>= 1; + } + if (a & 1) { + patch ^= 0x5b358fd3L; + } + a >>= 1; + } + patch ^= ~crc32(crc, buf, len - 4); + for (i = 0; i < 4; i++) { + buf[len - 4 + i] = patch & 0xff; + patch >>= 8; + } + /* Verify that we actually get the desired result */ + crc = crc32(0L, Z_NULL, 0); + crc = crc32(crc, buf, len); + if (crc != dcrc) { + errx(1, "CRC patching is broken: wanted %08x, but got %08x.", + dcrc, crc); + } +} + +void +usage() { + fprintf(stderr, "Usage:\n" + "jcgimage -o outfile -u uImage [-v version]\n" + "jcgimage -o outfile -k kernel -f rootfs [-v version]\n"); + exit(1); +} + +#define MODE_UNKNOWN 0 +#define MODE_UIMAGE 1 +#define MODE_KR 2 + +/* The output image must not be larger than 4MiB - 5*64kiB */ +#define MAXSIZE (size_t)(4 * 1024 * 1024 - 5 * 64 * 1024) + +int +main(int argc, char **argv) +{ + struct jcg_header *jh; + struct uimage_header *uh; + int c; + char *imagefile = NULL; + char *file1 = NULL; + char *file2 = NULL; + char *version = NULL; + int mode = MODE_UNKNOWN; + int fdo, fd1, fd2; + size_t size1, size2, sizeu, sizeo, off1, off2; + void *map; + + /* Make sure the headers have the right size */ + assert(sizeof(struct jcg_header) == 512); + assert(sizeof(struct uimage_header) == 64); + set_source_date_epoch(); + + while ((c = getopt(argc, argv, "o:k:f:u:v:h")) != -1) { + switch (c) { + case 'o': + imagefile = optarg; + break; + case 'k': + if (mode == MODE_UIMAGE) { + errx(1,"-k cannot be combined with -u"); + } + mode = MODE_KR; + file1 = optarg; + break; + case 'f': + if (mode == MODE_UIMAGE) { + errx(1,"-f cannot be combined with -u"); + } + mode = MODE_KR; + file2 = optarg; + break; + case 'u': + if (mode == MODE_KR) { + errx(1,"-u cannot be combined with -k and -r"); + } + mode = MODE_UIMAGE; + file1 = optarg; + break; + case 'v': + version = optarg; + break; + case 'h': + default: + usage(); + } + } + if (optind != argc) { + errx(1, "illegal arg \"%s\"", argv[optind]); + } + if (imagefile == NULL) { + errx(1, "no output file specified"); + } + if (mode == MODE_UNKNOWN) { + errx(1, "specify either -u or -k and -r"); + } + if (mode == MODE_KR) { + if (file1 == NULL || file2 == NULL) { + errx(1,"need -k and -r"); + } + fd2 = opensize(file2, &size2); + } + fd1 = opensize(file1, &size1); + if (mode == MODE_UIMAGE) { + off1 = sizeof(*jh); + sizeu = size1 + 4; + sizeo = sizeof(*jh) + sizeu; + } else { + off1 = sizeof(*jh) + sizeof(*uh); + off2 = sizeof(*jh) + sizeof(*uh) + size1; + sizeu = sizeof(*uh) + size1 + size2; + sizeo = sizeof(*jh) + sizeu; + } + + if (sizeo > MAXSIZE) { + errx(1,"payload too large: %zd > %zd\n", sizeo, MAXSIZE); + } + + fdo = open(imagefile, O_RDWR | O_CREAT | O_TRUNC, 00644); + if (fdo < 0) { + err(1, "cannot open \"%s\"", imagefile); + } + + if (ftruncate(fdo, sizeo) == -1) { + err(1, "cannot grow \"%s\" to %zd bytes", imagefile, sizeo); + } + map = mmap(NULL, sizeo, PROT_READ|PROT_WRITE, MAP_SHARED, fdo, 0); + uh = map + sizeof(*jh); + if (map == MAP_FAILED) { + err(1, "cannot mmap \"%s\"", imagefile); + } + + if (read(fd1, map + off1, size1) != size1) { + err(1, "cannot copy %s", file1); + } + + if (mode == MODE_KR) { + if (read(fd2, map+off2, size2) != size2) { + err(1, "cannot copy %s", file2); + } + mkuheader(uh, size1, size2); + } else if (mode == MODE_UIMAGE) { + craftcrc(ntohl(uh->ih_dcrc), (void*)uh + sizeof(*uh), + sizeu - sizeof(*uh)); + } + mkjcgheader(map, sizeu, version); + munmap(map, sizeo); + close(fdo); + return 0; +} diff --git a/tools/firmware-utils/src/lzma2eva.c b/tools/firmware-utils/src/lzma2eva.c index 0bc13fa4f34..1d7e3648899 100644 --- a/tools/firmware-utils/src/lzma2eva.c +++ b/tools/firmware-utils/src/lzma2eva.c @@ -48,7 +48,7 @@ main(int argc, char *argv[]) const char *infile, *outfile; FILE *in, *out; - static const uint8_t buf[4096]; + static uint8_t buf[4096]; size_t elems; uint8_t properties; diff --git a/tools/firmware-utils/src/md5.c b/tools/firmware-utils/src/md5.c index 20397603834..52d96accd30 100644 --- a/tools/firmware-utils/src/md5.c +++ b/tools/firmware-utils/src/md5.c @@ -1,307 +1,296 @@ - - /* - *********************************************************************** - ** md5.c -- the source code for MD5 routines ** - ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** - *********************************************************************** + * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. + * MD5 Message-Digest Algorithm (RFC 1321). + * + * Homepage: + * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + * + * Author: + * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> + * + * This software was written by Alexander Peslyak in 2001. No copyright is + * claimed, and the software is hereby placed in the public domain. + * In case this attempt to disclaim copyright and place the software in the + * public domain is deemed null and void, then the software is + * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * (This is a heavily cut-down "BSD license".) + * + * This differs from Colin Plumb's older public domain implementation in that + * no exactly 32-bit integer data type is required (any 32-bit or wider + * unsigned integer data type will do), there's no compile-time endianness + * configuration, and the function prototypes match OpenSSL's. No code from + * Colin Plumb's implementation has been reused; this comment merely compares + * the properties of the two independent implementations. + * + * The primary goals of this implementation are portability and ease of use. + * It is meant to be fast, but not as fast as possible. Some known + * optimizations are not included to reduce source code size and avoid + * compile-time configuration. */ -/* - *********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - *********************************************************************** - */ +#ifndef HAVE_OPENSSL #include <string.h> + #include "md5.h" /* - *********************************************************************** - ** Message-digest routines: ** - ** To form the message digest for a message M ** - ** (1) Initialize a context buffer mdContext using MD5_Init ** - ** (2) Call MD5_Update on mdContext and M ** - ** (3) Call MD5_Final on mdContext ** - ** The message digest is now in mdContext->digest[0...15] ** - *********************************************************************** + * The basic MD5 functions. + * + * F and G are optimized compared to their RFC 1321 definitions for + * architectures that lack an AND-NOT instruction, just like in Colin Plumb's + * implementation. + */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) (((x) ^ (y)) ^ (z)) +#define H2(x, y, z) ((x) ^ ((y) ^ (z))) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) + +/* + * The MD5 transformation for all four rounds. */ +#define STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); -/* forward declaration */ -static void Transform (); - -static unsigned char PADDING[64] = { - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* F, G, H and I are basic MD5 functions */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ -/* Rotation is separate from addition to prevent recomputation */ -#define FF(a, b, c, d, x, s, ac) \ - {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) \ - {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) \ - {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) \ - {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -#ifdef __STDC__ -#define UL(x) x##U +/* + * SET reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + * + * The check for little-endian architectures that tolerate unaligned + * memory accesses is just an optimization. Nothing will break if it + * doesn't work. + */ +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define SET(n) \ + (*(MD5_u32plus *)&ptr[(n) * 4]) +#define GET(n) \ + SET(n) #else -#define UL(x) x +#define SET(n) \ + (ctx->block[(n)] = \ + (MD5_u32plus)ptr[(n) * 4] | \ + ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ + ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ + ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) +#define GET(n) \ + (ctx->block[(n)]) #endif -/* The routine MD5_Init initializes the message-digest context - mdContext. All fields are set to zero. +/* + * This processes one or more 64-byte data blocks, but does NOT update + * the bit counters. There are no alignment requirements. */ -void MD5_Init (mdContext) -MD5_CTX *mdContext; +static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) { - mdContext->i[0] = mdContext->i[1] = (UINT4)0; - - /* Load magic initialization constants. - */ - mdContext->buf[0] = (UINT4)0x67452301; - mdContext->buf[1] = (UINT4)0xefcdab89; - mdContext->buf[2] = (UINT4)0x98badcfe; - mdContext->buf[3] = (UINT4)0x10325476; + const unsigned char *ptr; + MD5_u32plus a, b, c, d; + MD5_u32plus saved_a, saved_b, saved_c, saved_d; + + ptr = (const unsigned char *)data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + +/* Round 1 */ + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) + +/* Round 2 */ + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) + +/* Round 3 */ + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) + STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) + STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) + STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) + STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) + STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) + STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) + STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) + STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) + +/* Round 4 */ + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while (size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + return ptr; } -/* The routine MD5Update updates the message-digest context to - account for the presence of each of the characters inBuf[0..inLen-1] - in the message whose digest is being computed. - */ -void MD5_Update (mdContext, inBuf, inLen) -MD5_CTX *mdContext; -unsigned char *inBuf; -unsigned int inLen; +void MD5_Init(MD5_CTX *ctx) { - UINT4 in[16]; - int mdi; - unsigned int i, ii; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext->i[0] >> 3) & 0x3F); - - /* update number of bits */ - if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) - mdContext->i[1]++; - mdContext->i[0] += ((UINT4)inLen << 3); - mdContext->i[1] += ((UINT4)inLen >> 29); - - while (inLen--) { - /* add new character to buffer, increment mdi */ - mdContext->in[mdi++] = *inBuf++; - - /* transform if necessary */ - if (mdi == 0x40) { - for (i = 0, ii = 0; i < 16; i++, ii += 4) - in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | - (((UINT4)mdContext->in[ii+2]) << 16) | - (((UINT4)mdContext->in[ii+1]) << 8) | - ((UINT4)mdContext->in[ii]); - Transform (mdContext->buf, in); - mdi = 0; - } - } + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + + ctx->lo = 0; + ctx->hi = 0; } -/* The routine MD5Final terminates the message-digest computation and - ends with the desired message digest in mdContext->digest[0...15]. - */ -void MD5_Final (hash, mdContext) -unsigned char hash[]; -MD5_CTX *mdContext; +void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) { - UINT4 in[16]; - int mdi; - unsigned int i, ii; - unsigned int padLen; - - /* save number of bits */ - in[14] = mdContext->i[0]; - in[15] = mdContext->i[1]; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext->i[0] >> 3) & 0x3F); - - /* pad out to 56 mod 64 */ - padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); - MD5_Update (mdContext, PADDING, padLen); - - /* append length in bits and transform */ - for (i = 0, ii = 0; i < 14; i++, ii += 4) - in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | - (((UINT4)mdContext->in[ii+2]) << 16) | - (((UINT4)mdContext->in[ii+1]) << 8) | - ((UINT4)mdContext->in[ii]); - Transform (mdContext->buf, in); - - /* store buffer in digest */ - for (i = 0, ii = 0; i < 4; i++, ii += 4) { - mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); - mdContext->digest[ii+1] = - (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); - mdContext->digest[ii+2] = - (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); - mdContext->digest[ii+3] = - (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); - } - memcpy(hash, mdContext->digest, 16); + MD5_u32plus saved_lo; + unsigned long used, available; + + saved_lo = ctx->lo; + if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) + ctx->hi++; + ctx->hi += size >> 29; + + used = saved_lo & 0x3f; + + if (used) { + available = 64 - used; + + if (size < available) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, available); + data = (const unsigned char *)data + available; + size -= available; + body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = body(ctx, data, size & ~(unsigned long)0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); } -/* Basic MD5 step. Transforms buf based on in. - */ -static void Transform (buf, in) -UINT4 *buf; -UINT4 *in; +void MD5_Final(unsigned char *result, MD5_CTX *ctx) { - UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; - - /* Round 1 */ -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 - FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ - FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ - FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ - FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ - FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ - FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ - FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ - FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ - FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ - FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ - FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ - FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ - FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ - FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ - FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ - FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ - - /* Round 2 */ -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 - GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ - GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ - GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ - GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ - GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ - GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ - GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ - GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ - GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ - GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ - GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ - GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ - GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ - GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ - GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ - GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ - - /* Round 3 */ -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 - HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ - HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ - HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ - HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ - HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ - HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ - HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ - HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ - HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ - HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ - HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ - HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ - HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ - HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ - HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ - HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ - - /* Round 4 */ -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ - II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ - II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ - II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ - II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ - II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ - II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ - II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ - II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ - II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ - II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ - II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ - II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ - II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ - II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ - II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; + unsigned long used, available; + + used = ctx->lo & 0x3f; + + ctx->buffer[used++] = 0x80; + + available = 64 - used; + + if (available < 8) { + memset(&ctx->buffer[used], 0, available); + body(ctx, ctx->buffer, 64); + used = 0; + available = 64; + } + + memset(&ctx->buffer[used], 0, available - 8); + + ctx->lo <<= 3; + ctx->buffer[56] = ctx->lo; + ctx->buffer[57] = ctx->lo >> 8; + ctx->buffer[58] = ctx->lo >> 16; + ctx->buffer[59] = ctx->lo >> 24; + ctx->buffer[60] = ctx->hi; + ctx->buffer[61] = ctx->hi >> 8; + ctx->buffer[62] = ctx->hi >> 16; + ctx->buffer[63] = ctx->hi >> 24; + + body(ctx, ctx->buffer, 64); + + result[0] = ctx->a; + result[1] = ctx->a >> 8; + result[2] = ctx->a >> 16; + result[3] = ctx->a >> 24; + result[4] = ctx->b; + result[5] = ctx->b >> 8; + result[6] = ctx->b >> 16; + result[7] = ctx->b >> 24; + result[8] = ctx->c; + result[9] = ctx->c >> 8; + result[10] = ctx->c >> 16; + result[11] = ctx->c >> 24; + result[12] = ctx->d; + result[13] = ctx->d >> 8; + result[14] = ctx->d >> 16; + result[15] = ctx->d >> 24; + + memset(ctx, 0, sizeof(*ctx)); } -/* - *********************************************************************** - ** End of md5.c ** - ******************************** (cut) ******************************** - */ +#endif diff --git a/tools/firmware-utils/src/md5.h b/tools/firmware-utils/src/md5.h index f7a0c964183..2da44bf355a 100644 --- a/tools/firmware-utils/src/md5.h +++ b/tools/firmware-utils/src/md5.h @@ -1,65 +1,45 @@ /* - *********************************************************************** - ** md5.h -- header file for implementation of MD5 ** - ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** - ** Revised (for MD5): RLR 4/27/91 ** - ** -- G modified to have y&~z instead of y&z ** - ** -- FF, GG, HH modified to add in last register done ** - ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** - ** -- distinct additive constant for each step ** - ** -- round 4 added, working mod 7 ** - *********************************************************************** + * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. + * MD5 Message-Digest Algorithm (RFC 1321). + * + * Homepage: + * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + * + * Author: + * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> + * + * This software was written by Alexander Peslyak in 2001. No copyright is + * claimed, and the software is hereby placed in the public domain. + * In case this attempt to disclaim copyright and place the software in the + * public domain is deemed null and void, then the software is + * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the + * general public under the following terms: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + * + * See md5.c for more information. */ -/* - *********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - *********************************************************************** - */ +#ifdef HAVE_OPENSSL +#include <openssl/md5.h> +#elif !defined(_MD5_H) +#define _MD5_H -#ifndef __MD5_INCLUDE__ +/* Any 32-bit or wider unsigned integer data type will do */ +typedef unsigned int MD5_u32plus; -/* typedef a 32-bit type */ -#ifdef _LP64 -typedef unsigned int UINT4; -typedef int INT4; -#else -typedef unsigned long UINT4; -typedef long INT4; -#endif -#define _UINT4_T - -/* Data structure for MD5 (Message-Digest) computation */ typedef struct { - UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ - UINT4 buf[4]; /* scratch buffer */ - unsigned char in[64]; /* input buffer */ - unsigned char digest[16]; /* actual digest after MD5Final call */ + MD5_u32plus lo, hi; + MD5_u32plus a, b, c, d; + unsigned char buffer[64]; + MD5_u32plus block[16]; } MD5_CTX; -void MD5_Init (); -void MD5_Update (); -void MD5_Final (); +extern void MD5_Init(MD5_CTX *ctx); +extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size); +extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); -#define __MD5_INCLUDE__ -#endif /* __MD5_INCLUDE__ */ +#endif diff --git a/tools/firmware-utils/src/mkbrnimg.c b/tools/firmware-utils/src/mkbrnimg.c index fff92c4ef66..b7a73ff59d2 100644 --- a/tools/firmware-utils/src/mkbrnimg.c +++ b/tools/firmware-utils/src/mkbrnimg.c @@ -32,9 +32,14 @@ static uint32_t crc32[1<<BPB]; +static char *output_file = "default-brnImage"; +static uint32_t magic = 0x12345678; +static char *signature = "BRNDTW502"; +static uint32_t crc32_poly = 0x2083b8ed; + static void init_crc32() { - const uint32_t poly = ntohl(0x2083b8ed); + const uint32_t poly = ntohl(crc32_poly); int n; for (n = 0; n < 1<<BPB; n++) { @@ -61,21 +66,17 @@ static void usage(const char *) __attribute__ (( __noreturn__ )); static void usage(const char *mess) { fprintf(stderr, "Error: %s\n", mess); - fprintf(stderr, "Usage: mkbrnimg [-o output_file] [-m magic] [-s signature] kernel_file [additional files]\n"); + fprintf(stderr, "Usage: mkbrnimg [-o output_file] [-m magic] [-s signature] [-p crc32 poly] kernel_file [additional files]\n"); fprintf(stderr, "\n"); exit(1); } -static char *output_file = "default-brnImage"; -static uint32_t magic = 0x12345678; -static char *signature = "BRNDTW502"; - static void parseopts(int *argc, char ***argv) { char *endptr; int res; - while ((res = getopt(*argc, *argv, "o:m:s:")) != -1) { + while ((res = getopt(*argc, *argv, "o:m:s:p:")) != -1) { switch (res) { default: usage("Unknown option"); @@ -91,6 +92,11 @@ static void parseopts(int *argc, char ***argv) case 's': signature = optarg; break; + case 'p': + crc32_poly = strtoul(optarg, &endptr, 0); + if (endptr == optarg || *endptr != 0) + usage("'crc32 poly' must be a decimal or hexadecimal 32-bit value"); + break; } } *argc -= optind; @@ -136,7 +142,7 @@ static void appendfile(int outfd, char *path, int kernel) { // write padding padded_len = ((len + sizeof(footer) + sizeof(padding) - 1) & ~(sizeof(padding) - 1)) - sizeof(footer); - fprintf(stderr, "len=%08x padded_len=%08x\n", len, padded_len); + fprintf(stderr, "len=%08zx padded_len=%08zx\n", len, padded_len); write(outfd, padding, padded_len - len); // write footer diff --git a/tools/firmware-utils/src/mkbuffaloimg.c b/tools/firmware-utils/src/mkbuffaloimg.c new file mode 100644 index 00000000000..364dda005b0 --- /dev/null +++ b/tools/firmware-utils/src/mkbuffaloimg.c @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2016 FUKAUMI Naoki <naobsd@gmail.com> + * + * Based on mkdniimg.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> /* for unlink() */ +#include <libgen.h> +#include <getopt.h> /* for getopt() */ +#include <stdarg.h> +#include <errno.h> +#include <sys/stat.h> + +#define DNI_HDR_LEN 128 + +/* + * Globals + */ +static char *ifname; +static char *progname; +static char *ofname; +static char *version = "0.00_0.00"; +static char *region = "JP"; +static char *rootfs_size; +static char *kernel_size; + +static char *board_id; +/* + * Message macros + */ +#define ERR(fmt, ...) do { \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt "\n", \ + progname, ## __VA_ARGS__ ); \ +} while (0) + +#define ERRS(fmt, ...) do { \ + int save = errno; \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ + progname, ## __VA_ARGS__, strerror(save)); \ +} while (0) + +void usage(int status) +{ + FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; + + fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stream, +"\n" +"Options:\n" +" -B <board> create image for the board specified with <board>\n" +" -i <file> read input from the file <file>\n" +" -o <file> write output to the file <file>\n" +" -v <version> set image version to <version>\n" +" -r <region> set image region to <region>\n" +" -R <rootfs_size> set RootfsSize to <rootfs_size>\n" +" -K <kernel_size> set KernelSize to <kernel_size>\n" +" -h show this screen\n" + ); + + exit(status); +} + +int main(int argc, char *argv[]) +{ + int res = EXIT_FAILURE; + int buflen; + int err; + struct stat st; + char *buf; + int i; + uint8_t csum; + + FILE *outfile, *infile; + + progname = basename(argv[0]); + + while ( 1 ) { + int c; + + c = getopt(argc, argv, "B:i:o:v:r:R:K:h"); + if (c == -1) + break; + + switch (c) { + case 'B': + board_id = optarg; + break; + case 'i': + ifname = optarg; + break; + case 'o': + ofname = optarg; + break; + case 'v': + version = optarg; + break; + case 'r': + region = optarg; + break; + case 'R': + rootfs_size = optarg; + break; + case 'K': + kernel_size = optarg; + break; + case 'h': + usage(EXIT_SUCCESS); + break; + default: + usage(EXIT_FAILURE); + break; + } + } + + if (board_id == NULL) { + ERR("no board specified"); + goto err; + } + + if (rootfs_size == NULL) { + ERR("no rootfs_size specified"); + goto err; + } + + if (kernel_size == NULL) { + ERR("no kernel_size specified"); + goto err; + } + + if (ifname == NULL) { + ERR("no input file specified"); + goto err; + } + + if (ofname == NULL) { + ERR("no output file specified"); + goto err; + } + + err = stat(ifname, &st); + if (err){ + ERRS("stat failed on %s", ifname); + goto err; + } + + buflen = st.st_size + DNI_HDR_LEN + 1; + buf = malloc(buflen); + if (!buf) { + ERR("no memory for buffer\n"); + goto err; + } + + memset(buf, 0, DNI_HDR_LEN); + snprintf(buf, DNI_HDR_LEN, "device:%s\nversion:%s\nregion:%s\n" + "RootfsSize:%s\nKernelSize:%s\nInfoHeadSize:128\n", + board_id, version, region, rootfs_size, kernel_size); + buf[DNI_HDR_LEN - 2] = 0x12; + buf[DNI_HDR_LEN - 1] = 0x32; + + infile = fopen(ifname, "r"); + if (infile == NULL) { + ERRS("could not open \"%s\" for reading", ifname); + goto err_free; + } + + errno = 0; + fread(buf + DNI_HDR_LEN, st.st_size, 1, infile); + if (errno != 0) { + ERRS("unable to read from file %s", ifname); + goto err_close_in; + } + + csum = 0; + for (i = 0; i < (st.st_size + DNI_HDR_LEN); i++) + csum += buf[i]; + + csum = 0xff - csum; + buf[st.st_size + DNI_HDR_LEN] = csum; + + outfile = fopen(ofname, "w"); + if (outfile == NULL) { + ERRS("could not open \"%s\" for writing", ofname); + goto err_close_in; + } + + errno = 0; + fwrite(buf, buflen, 1, outfile); + if (errno) { + ERRS("unable to write to file %s", ofname); + goto err_close_out; + } + + res = EXIT_SUCCESS; + + fflush(outfile); + + err_close_out: + fclose(outfile); + if (res != EXIT_SUCCESS) { + unlink(ofname); + } + + err_close_in: + fclose(infile); + + err_free: + free(buf); + + err: + return res; +} diff --git a/tools/firmware-utils/src/mkcameofw.c b/tools/firmware-utils/src/mkcameofw.c new file mode 100644 index 00000000000..e0da4baf330 --- /dev/null +++ b/tools/firmware-utils/src/mkcameofw.c @@ -0,0 +1,433 @@ +/* + * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> /* for unlink() */ +#include <libgen.h> +#include <getopt.h> /* for getopt() */ +#include <stdarg.h> +#include <errno.h> +#include <sys/stat.h> + +#include <arpa/inet.h> +#include <netinet/in.h> + +#define MAX_MODEL_LEN 20 +#define MAX_SIGNATURE_LEN 30 +#define MAX_REGION_LEN 4 +#define MAX_VERSION_LEN 12 + +#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) + +struct file_info { + char *file_name; /* name of the file */ + uint32_t file_size; /* length of the file */ + uint32_t write_size; +}; + +struct img_header { + uint32_t checksum; + uint32_t image_size; + uint32_t kernel_size; + char model[MAX_MODEL_LEN]; + char signature[MAX_SIGNATURE_LEN]; + char region[MAX_REGION_LEN]; + char version[MAX_VERSION_LEN]; + unsigned char header_len; + unsigned char is_tgz; + unsigned char pad[4]; +} __attribute__ ((packed)); + +/* + * Globals + */ +static char *ofname; +static char *progname; + +static char *model; +static char *signature; +static char *region = "DEF"; +static char *version; +static struct file_info kernel_info; +static struct file_info rootfs_info; +static uint32_t kernel_size; +static uint32_t image_size; +static int combined; + +/* + * Message macros + */ +#define ERR(fmt, ...) do { \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt "\n", \ + progname, ## __VA_ARGS__ ); \ +} while (0) + +#define ERRS(fmt, ...) do { \ + int save = errno; \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt " (%s)\n", \ + progname, ## __VA_ARGS__, strerror(save)); \ +} while (0) + +#define DBG(fmt, ...) do { \ + fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ +} while (0) + +static void usage(int status) +{ + FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; + + fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stream, +"\n" +"Options:\n" +" -k <file> read kernel image from the file <file>\n" +" -c use the kernel image as a combined image\n" +" -M <model> set model to <model>\n" +" -o <file> write output to the file <file>\n" +" -r <file> read rootfs image from the file <file>\n" +" -S <signature> set image signature to <signature>\n" +" -R <region> set image region to <region>\n" +" -V <version> set image version to <version>\n" +" -I <size> set image size to <size>\n" +" -K <size> set kernel size to <size>\n" +" -h show this screen\n" + ); + + exit(status); +} + +int +str2u32(char *arg, uint32_t *val) +{ + char *err = NULL; + uint32_t t; + + errno=0; + t = strtoul(arg, &err, 0); + if (errno || (err==arg) || ((err != NULL) && *err)) { + return -1; + } + + *val = t; + return 0; +} + +static int get_file_stat(struct file_info *fdata) +{ + struct stat st; + int res; + + if (fdata->file_name == NULL) + return 0; + + res = stat(fdata->file_name, &st); + if (res){ + ERRS("stat failed on %s", fdata->file_name); + return res; + } + + fdata->file_size = st.st_size; + fdata->write_size = fdata->file_size; + return 0; +} + +static int read_to_buf(struct file_info *fdata, char *buf) +{ + FILE *f; + int ret = EXIT_FAILURE; + + f = fopen(fdata->file_name, "r"); + if (f == NULL) { + ERRS("could not open \"%s\" for reading", fdata->file_name); + goto out; + } + + errno = 0; + fread(buf, fdata->file_size, 1, f); + if (errno != 0) { + ERRS("unable to read from file \"%s\"", fdata->file_name); + goto out_close; + } + + ret = EXIT_SUCCESS; + +out_close: + fclose(f); +out: + return ret; +} + +static int check_options(void) +{ + int ret; + +#define CHKSTR(_name, _msg) \ + do { \ + if (_name == NULL) { \ + ERR("no %s specified", _msg); \ + return -1; \ + } \ + } while (0) + +#define CHKSTRLEN(_name, _msg) \ + do { \ + int field_len; \ + CHKSTR(_name, _msg); \ + field_len = FIELD_SIZEOF(struct img_header, _name) - 1; \ + if (strlen(_name) > field_len) { \ + ERR("%s is too long, max length is %d", \ + _msg, field_len); \ + return -1; \ + } \ + } while (0) + + CHKSTRLEN(model, "model"); + CHKSTRLEN(signature, "signature"); + CHKSTRLEN(region, "region"); + CHKSTRLEN(version, "version"); + CHKSTR(ofname, "output file"); + CHKSTR(kernel_info.file_name, "kernel image"); + + ret = get_file_stat(&kernel_info); + if (ret) + return ret; + + if (combined) { + if (!kernel_size) { + ERR("kernel size must be specified for combined images"); + return -1; \ + } + + if (!image_size) + image_size = kernel_info.file_size; + + if (kernel_info.file_size > image_size) { + ERR("kernel image is too big"); + return -1; + } + + kernel_info.write_size = image_size; + } else { + CHKSTR(rootfs_info.file_name, "rootfs image"); + + ret = get_file_stat(&rootfs_info); + if (ret) + return ret; + + if (kernel_size) { + /* override kernel size */ + kernel_info.write_size = kernel_size; + } + + if (image_size) { + if (image_size < kernel_info.write_size) + kernel_info.write_size = image_size; + + /* override rootfs size */ + rootfs_info.write_size = image_size - kernel_info.write_size; + } + + if (kernel_info.file_size > kernel_info.write_size) { + ERR("kernel image is too big"); + return -1; + } + + if (rootfs_info.file_size > rootfs_info.write_size) { + ERR("rootfs image is too big"); + return -1; + } + } + + return 0; +} + +static int write_fw(char *data, int len) +{ + FILE *f; + int ret = EXIT_FAILURE; + + f = fopen(ofname, "w"); + if (f == NULL) { + ERRS("could not open \"%s\" for writing", ofname); + goto out; + } + + errno = 0; + fwrite(data, len, 1, f); + if (errno) { + ERRS("unable to write output file"); + goto out_flush; + } + + DBG("firmware file \"%s\" completed", ofname); + + ret = EXIT_SUCCESS; + +out_flush: + fflush(f); + fclose(f); + if (ret != EXIT_SUCCESS) { + unlink(ofname); + } +out: + return ret; +} + +static uint32_t get_csum(unsigned char *p, uint32_t len) +{ + uint32_t csum = 0; + + while (len--) + csum += *p++; + + return csum; +} + +static int build_fw(void) +{ + int buflen; + char *buf; + char *p; + uint32_t csum; + struct img_header *hdr; + int ret = EXIT_FAILURE; + + buflen = sizeof(struct img_header) + + kernel_info.write_size + rootfs_info.write_size; + + buf = malloc(buflen); + if (!buf) { + ERR("no memory for buffer\n"); + goto out; + } + + memset(buf, 0, buflen); + + p = buf + sizeof(struct img_header); + + /* read kernel data */ + ret = read_to_buf(&kernel_info, p); + if (ret) + goto out_free_buf; + + if (!combined) { + p += kernel_info.write_size; + + /* read rootfs data */ + ret = read_to_buf(&rootfs_info, p); + if (ret) + goto out_free_buf; + } + + csum = get_csum((unsigned char *)(buf + sizeof(struct img_header)), + buflen - sizeof(struct img_header)); + + /* fill firmware header */ + hdr = (struct img_header *) buf; + + hdr->checksum = htonl(csum); + hdr->image_size = htonl(buflen - sizeof(struct img_header)); + if (!combined) + hdr->kernel_size = htonl(kernel_info.write_size); + else + hdr->kernel_size = htonl(kernel_size); + hdr->header_len = sizeof(struct img_header); + strncpy(hdr->model, model, sizeof(hdr->model)); + strncpy(hdr->signature, signature, sizeof(hdr->signature)); + strncpy(hdr->version, version, sizeof(hdr->version)); + strncpy(hdr->region, region, sizeof(hdr->region)); + + ret = write_fw(buf, buflen); + if (ret) + goto out_free_buf; + + ret = EXIT_SUCCESS; + +out_free_buf: + free(buf); +out: + return ret; +} + +int main(int argc, char *argv[]) +{ + int ret = EXIT_FAILURE; + + progname = basename(argv[0]); + + while (1) { + int c; + + c = getopt(argc, argv, "M:S:V:R:k:K:I:r:o:hc"); + if (c == -1) + break; + + switch (c) { + case 'M': + model = optarg; + break; + case 'S': + signature = optarg; + break; + case 'V': + version = optarg; + break; + case 'R': + region = optarg; + break; + case 'k': + kernel_info.file_name = optarg; + break; + case 'K': + if (str2u32(optarg, &kernel_size)) { + ERR("%s is invalid '%s'", + "kernel size", optarg); + goto out; + } + break; + case 'I': + if (str2u32(optarg, &image_size)) { + ERR("%s is invalid '%s'", + "image size", optarg); + goto out; + } + break; + case 'r': + rootfs_info.file_name = optarg; + break; + case 'c': + combined = 1; + break; + case 'o': + ofname = optarg; + break; + case 'h': + usage(EXIT_SUCCESS); + break; + default: + usage(EXIT_FAILURE); + break; + } + } + + ret = check_options(); + if (ret) + goto out; + + ret = build_fw(); + +out: + return ret; +} + diff --git a/tools/firmware-utils/src/mkcasfw.c b/tools/firmware-utils/src/mkcasfw.c index 626e77d4c49..5655bf1894c 100644 --- a/tools/firmware-utils/src/mkcasfw.c +++ b/tools/firmware-utils/src/mkcasfw.c @@ -258,7 +258,7 @@ static struct board_info boards[] = { #define ERRS(fmt, ...) do { \ int save = errno; \ fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ + fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ progname, ## __VA_ARGS__, strerror(save)); \ } while (0) @@ -708,7 +708,7 @@ image_writeout(FILE *outfile, struct image_desc *desc) /* write padding data if neccesary */ padlen = desc->out_size - desc->file_size; - DBG(1,"padding desc, length=%d", padlen); + DBG(1,"padding desc, length=%zu", padlen); res = write_out_padding(outfile, padlen, desc->padc, &css); desc->csum = csum_get(&css); @@ -985,11 +985,11 @@ main(int argc, char *argv[]) res = ERR_FATAL; if (keep_invalid_images == 0) { - WARN("generation of invalid images disabled", ofname); + WARN("generation of invalid images \"%s\" disabled", ofname); goto out; } - WARN("generating invalid image", ofname); + WARN("generating invalid image: \"%s\"", ofname); } outfile = fopen(ofname, "w"); diff --git a/tools/firmware-utils/src/mkchkimg.c b/tools/firmware-utils/src/mkchkimg.c index e152f7d4685..0fe01f07079 100644 --- a/tools/firmware-utils/src/mkchkimg.c +++ b/tools/firmware-utils/src/mkchkimg.c @@ -31,6 +31,20 @@ #define MAX_BOARD_ID_LEN (64) +/* + * Note on the reserved field of the chk_header: + * OFW naming scheme is typically: DEVICENAME-VA.B.C.D_E.F.G.chk, with A-G + * between 0 and 255. For instance: EX3700_EX3800-V1.0.0.58_1.0.38.chk + * The reserved field works like this: + * reserved[0]: region code. 1 for WW (WorldWide) and 2 for NA (North America) + * reserved[1]: A + * reserved[2]: B + * reserved[3]: C + * reserved[4]: D + * reserved[5]: E + * reserved[6]: F + * reserved[7]: G + */ struct chk_header { uint32_t magic; uint32_t header_len; @@ -248,10 +262,10 @@ main (int argc, char * argv[]) hdr->reserved[1] = 1; /* Major */ hdr->reserved[2] = 1; /* Minor */ hdr->reserved[3] = 99; /* Build */ - hdr->reserved[4] = 0; /* Unknown t1 ? was 1 */ - hdr->reserved[5] = 0; /* Unknonw t2 ? was 0 */ - hdr->reserved[6] = 0; /* Unknonw t3 ? was 1 */ - hdr->reserved[7] = 0; /* Unused ? */ + hdr->reserved[4] = 0; + hdr->reserved[5] = 0; + hdr->reserved[6] = 0; + hdr->reserved[7] = 0; message (" Board Id: %s", board_id); message (" Region: %s", region == 1 ? "World Wide (WW)" : (region == 2 ? "North America (NA)" : "Unknown")); diff --git a/tools/firmware-utils/src/mkcsysimg.c b/tools/firmware-utils/src/mkcsysimg.c index 4f2352a60e7..77fbbaa57fa 100644 --- a/tools/firmware-utils/src/mkcsysimg.c +++ b/tools/firmware-utils/src/mkcsysimg.c @@ -160,6 +160,7 @@ static struct board_info boards[] = { BOARD_ADM("BR-6114WG", "Edimax BR-6114WG", 2, SIG_BR6114WG), BOARD_ADM("BR-6524K", "Edimax BR-6524K", 2, SIG_BR6524K), BOARD_ADM("BR-6524KP", "Edimax BR-6524KP", 2, SIG_BR6524KP), + BOARD_ADM("BR-6524N", "Edimax BR-6524N", 2, SIG_BR6524N), BOARD_ADM("BR-6524WG", "Edimax BR-6524WG", 4, SIG_BR6524WG), BOARD_ADM("BR-6524WP", "Edimax BR-6524WP", 4, SIG_BR6524WP), BOARD_ADM("BR-6541K", "Edimax BR-6541K", 2, SIG_BR6541K), @@ -198,7 +199,7 @@ static struct board_info boards[] = { #define ERRS(fmt, ...) do { \ int save = errno; \ fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", progname, ## __VA_ARGS__ \ + fprintf(stderr, "[%s] *** error: " fmt ": %s\n", progname, ## __VA_ARGS__ \ , strerror(save)); \ } while (0) @@ -646,7 +647,7 @@ block_writeout_data(FILE *outfile, struct csys_block *block) /* write padding data if neccesary */ padlen = block->size_avail - block->file_size; - DBG(1,"padding block, length=%d", padlen); + DBG(1,"padding block, length=%zu", padlen); res = write_out_padding(outfile, padlen, block->padc, block->css); return res; @@ -1121,11 +1122,11 @@ main(int argc, char *argv[]) res = ERR_FATAL; if (keep_invalid_images == 0) { - WARN("generation of invalid images disabled", ofname); + WARN("generation of invalid images \"%s\" disabled", ofname); goto out; } - WARN("generating invalid image", ofname); + WARN("generating invalid image: \"%s\"", ofname); } outfile = fopen(ofname, "w"); diff --git a/tools/firmware-utils/src/mkdapimg.c b/tools/firmware-utils/src/mkdapimg.c new file mode 100644 index 00000000000..ed662d8ecc0 --- /dev/null +++ b/tools/firmware-utils/src/mkdapimg.c @@ -0,0 +1,226 @@ +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <libgen.h> +#include <stdarg.h> +#include <getopt.h> +#include <string.h> +#include <errno.h> + +#include <netinet/in.h> // htonl + +// Usage: mkdapimg [-p] [-m <model>] -s <sig> -i <input> -o <output> +// +// e.g.: mkdapimg -s RT3052-AP-DAP1350-3 -i sysupgarde.bin -o factory.bin +// +// If the model string <model> is not given, we will assume that +// the leading characters upto the first "-" is the model. +// +// The "-p" (patch) option is used to patch the exisiting image with the +// specified model and signature. +// The "-x" (fix) option will recalculate the payload size and checksum +// during the patch mode operation. + +// The img_hdr_struct was taken from the D-Link SDK: +// DAP-1350_A1_FW1.11NA_GPL/GPL_Source_Code/Uboot/DAP-1350/httpd/header.h + +#define MAX_MODEL_NAME_LEN 20 +#define MAX_SIG_LEN 30 +#define MAX_REGION_LEN 4 +#define MAX_VERSION_LEN 12 + +struct img_hdr_struct { + uint32_t checksum; + char model[MAX_MODEL_NAME_LEN]; + char sig[MAX_SIG_LEN]; + uint8_t partition; + uint8_t hdr_len; + uint8_t rsv1; + uint8_t rsv2; + uint32_t flash_byte_cnt; +} imghdr ; + +char *progname; + +void +perrexit(int code, char *msg) +{ + fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(errno)); + exit(code); +} + +void +usage() +{ + fprintf(stderr, "usage: %s [-p] [-m model] [-r region] [-v version] -s signature -i input -o output\n", progname); + exit(1); +} + +int +main(int ac, char *av[]) +{ + char model[MAX_MODEL_NAME_LEN+1]; + char signature[MAX_SIG_LEN+1]; + char region[MAX_REGION_LEN+1]; + char version[MAX_VERSION_LEN+1]; + int patchmode = 0; + int fixmode = 0; + int have_regionversion = 0; + + FILE *ifile, *ofile; + int c; + uint32_t cksum; + uint32_t bcnt; + + progname = basename(av[0]); + memset(model, 0, sizeof(model)); + memset(signature, 0, sizeof(signature)); + memset(region, 0, sizeof(region)); + memset(version, 0, sizeof(version)); + + while ( 1 ) { + int c; + + c = getopt(ac, av, "pxm:r:v:s:i:o:"); + if (c == -1) + break; + + switch (c) { + case 'p': + patchmode = 1; + break; + case 'x': + fixmode = 1; + break; + case 'm': + if (strlen(optarg) > MAX_MODEL_NAME_LEN) { + fprintf(stderr, "%s: model name exceeds %d chars\n", + progname, MAX_MODEL_NAME_LEN); + exit(1); + } + strcpy(model, optarg); + break; + case 'r': + if (strlen(optarg) > MAX_REGION_LEN) { + fprintf(stderr, "%s: region exceeds %d chars\n", + progname, MAX_REGION_LEN); + exit(1); + } + have_regionversion = 1; + strcpy(region, optarg); + break; + case 'v': + if (strlen(optarg) > MAX_VERSION_LEN) { + fprintf(stderr, "%s: version exceeds %d chars\n", + progname, MAX_VERSION_LEN); + exit(1); + } + have_regionversion = 1; + strcpy(version, optarg); + break; + case 's': + if (strlen(optarg) > MAX_SIG_LEN) { + fprintf(stderr, "%s: signature exceeds %d chars\n", + progname, MAX_SIG_LEN); + exit(1); + } + strcpy(signature, optarg); + break; + case 'i': + if ((ifile = fopen(optarg, "r")) == NULL) + perrexit(1, optarg); + break; + case 'o': + if ((ofile = fopen(optarg, "w")) == NULL) + perrexit(1, optarg); + break; + default: + usage(); + } + } + + if (signature[0] == 0 || ifile == NULL || ofile == NULL) { + usage(); + } + + if (model[0] == 0) { + char *p = strchr(signature, '-'); + if (p == NULL) { + fprintf(stderr, "%s: model name unknown\n", progname); + exit(1); + } + if (p - signature > MAX_MODEL_NAME_LEN) { + *p = 0; + fprintf(stderr, "%s: auto model name failed, string %s too long\n", progname, signature); + exit(1); + } + strncpy(model, signature, p - signature); + } + + if (patchmode) { + if (fread(&imghdr, sizeof(imghdr), 1, ifile) < 0) + perrexit(2, "fread on input"); + } + + for (bcnt = 0, cksum = 0 ; (c = fgetc(ifile)) != EOF ; bcnt++) + cksum += c & 0xff; + + if (fseek(ifile, patchmode ? sizeof(imghdr) : 0, SEEK_SET) < 0) + perrexit(2, "fseek on input"); + + if (patchmode == 0) { + // Fill in the header + memset(&imghdr, 0, sizeof(imghdr)); + imghdr.checksum = htonl(cksum); + imghdr.partition = 0 ; // don't care? + imghdr.hdr_len = sizeof(imghdr); + if (have_regionversion) { + imghdr.hdr_len += MAX_REGION_LEN; + imghdr.hdr_len += MAX_VERSION_LEN; + } + imghdr.flash_byte_cnt = htonl(bcnt); + } else { + if (ntohl(imghdr.checksum) != cksum) { + fprintf(stderr, "%s: patch mode, checksum mismatch\n", + progname); + if (fixmode) { + fprintf(stderr, "%s: fixing\n", progname); + imghdr.checksum = htonl(cksum); + } else + exit(3); + } else if (ntohl(imghdr.flash_byte_cnt) != bcnt) { + fprintf(stderr, "%s: patch mode, size mismatch\n", + progname); + if (fixmode) { + fprintf(stderr, "%s: fixing\n", progname); + imghdr.flash_byte_cnt = htonl(bcnt); + } else + exit(3); + } + } + + strncpy(imghdr.model, model, MAX_MODEL_NAME_LEN); + strncpy(imghdr.sig, signature, MAX_SIG_LEN); + + if (fwrite(&imghdr, sizeof(imghdr), 1, ofile) < 0) + perrexit(2, "fwrite header on output"); + if (have_regionversion) { + if (fwrite(®ion, MAX_REGION_LEN, 1, ofile) < 0) + perrexit(2, "fwrite header on output"); + if (fwrite(&version, MAX_VERSION_LEN, 1, ofile) < 0) + perrexit(2, "fwrite header on output"); + } + + while ((c = fgetc(ifile)) != EOF) { + if (fputc(c, ofile) == EOF) + perrexit(2, "fputc on output"); + } + + if (ferror(ifile)) + perrexit(2, "fgetc on input"); + + + fclose(ofile); + fclose(ifile); +} diff --git a/tools/firmware-utils/src/mkdapimg2.c b/tools/firmware-utils/src/mkdapimg2.c new file mode 100644 index 00000000000..aef003c280c --- /dev/null +++ b/tools/firmware-utils/src/mkdapimg2.c @@ -0,0 +1,204 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License, + * version 2 as published by the Free Software Foundation. + * + * (C) Nicolò Veronese <nicveronese@gmail.com> + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <libgen.h> +#include <stdarg.h> +#include <getopt.h> +#include <string.h> +#include <errno.h> + +#include <netinet/in.h> // htonl + +// Usage: mkdapimg2 -s signature [-v version] [-r region] +// [-k uImage block size] -i <input> -o <output> +// +// NOTE: The kernel block size is used to know the offset of the rootfs +// in the image file. +// +// The system writes in the uImage partition until the end of uImage +// is reached, after that, the system jumps to the offset specified with the -k +// parameter and begin writing at the beginning of the rootfs MTD partition. +// +// If the -k parameter is the size of the original uImage partition, the system +// continue writing in the rootfs partition starting from the last block +// that has been wrote. (This is useful if the new kernel size is +// different from the original one) +// +// Example: +// ------------------------------------------ +// Creating 7 MTD partitions on "ath-nor0": +// 0x000000000000-0x000000010000 : "u-boot" +// 0x000000010000-0x000000020000 : "ART" +// 0x000000020000-0x000000030000 : "MP" +// 0x000000030000-0x000000040000 : "config" +// 0x000000040000-0x000000120000 : "uImage" +// 0x000000120000-0x000000800000 : "rootfs" +// 0x000000040000-0x000000800000 : "firmware" +// ------------------------------------------ +// +// 0x000000120000-0x000000040000 = 0xE0000 -> 917504 +// +// e.g.: mkdapimg2 -s HONEYBEE-FIRMWARE-DAP-1330 -v 1.00.21 -r Default +// -k 917504 -i sysupgarde.bin -o factory.bin +// +// +// The img_hdr_struct was taken from the D-Link SDK: +// DAP-1330_OSS-firmware_1.00b21/DAP-1330_OSS-firmware_1.00b21/uboot/uboot.patch + +#define MAX_SIGN_LEN 32 +#define MAX_FW_VER_LEN 16 +#define MAX_REG_LEN 8 + +struct img_hdr_struct { + uint32_t hdr_len; + uint32_t checksum; + uint32_t total_size; + uint32_t kernel_size; + char signature[MAX_SIGN_LEN]; + char fw_ver[MAX_FW_VER_LEN]; + char fw_reg[MAX_REG_LEN]; +} imghdr ; + +char *progname; + +void +perrexit(int code, char *msg) +{ + fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(errno)); + exit(code); +} + +void +usage() +{ + fprintf(stderr, "usage: %s -s signature [-v version] [-r region] [-k uImage part size] -i <input> -o <output>\n", progname); + exit(1); +} + +int +main(int ac, char *av[]) +{ + char signature[MAX_SIGN_LEN]; + char version[MAX_FW_VER_LEN]; + char region[MAX_REG_LEN]; + int kernel = 0; + + FILE *ifile, *ofile; + int c; + + uint32_t cksum; + uint32_t bcnt; + + progname = basename(av[0]); + + memset(signature, 0, sizeof(signature)); + memset(version, 0, sizeof(version)); + memset(region, 0, sizeof(region)); + + while ( 1 ) { + char *ptr; + int c; + + c = getopt(ac, av, "s:v:r:k:i:o:"); + if (c == -1) + break; + + switch (c) { + case 's': + if (strlen(optarg) > MAX_SIGN_LEN + 1) { + fprintf(stderr, "%s: signature exceeds %d chars\n", + progname, MAX_SIGN_LEN); + exit(1); + } + strcpy(signature, optarg); + break; + case 'v': + if (strlen(optarg) > MAX_FW_VER_LEN + 1) { + fprintf(stderr, "%s: version exceeds %d chars\n", + progname, MAX_FW_VER_LEN); + exit(1); + } + strcpy(version, optarg); + break; + case 'r': + if (strlen(optarg) > MAX_REG_LEN + 1) { + fprintf(stderr, "%s: region exceeds %d chars\n", + progname, MAX_REG_LEN); + exit(1); + } + strcpy(region, optarg); + break; + case 'k': + kernel = strtoul(optarg, &ptr, 0); + if(ptr[0] == 'k'){ + kernel *= 1000; + } + break; + case 'i': + if ((ifile = fopen(optarg, "r")) == NULL) + perrexit(1, optarg); + break; + case 'o': + if ((ofile = fopen(optarg, "w")) == NULL) + perrexit(1, optarg); + break; + default: + usage(); + } + } + + if (signature[0] == 0 || ifile == NULL || ofile == NULL) { + usage(); + exit(1); + } + + for (bcnt = 0, cksum = 0 ; (c = fgetc(ifile)) != EOF ; bcnt++) + cksum += c & 0xff; + + if (fseek(ifile, 0, SEEK_SET) < 0) + perrexit(2, "fseek on input"); + + // Fill in the header + memset(&imghdr, 0, sizeof(imghdr)); + imghdr.hdr_len = sizeof(imghdr); + imghdr.checksum = htonl(cksum); + imghdr.total_size = htonl(bcnt); + imghdr.kernel_size = htonl(kernel); + + strncpy(imghdr.signature, signature, MAX_SIGN_LEN); + strncpy(imghdr.fw_ver, version, MAX_FW_VER_LEN); + strncpy(imghdr.fw_reg, region, MAX_REG_LEN); + + if (fwrite(&imghdr, sizeof(imghdr), 1, ofile) < 0) + perrexit(2, "fwrite header on output"); + + while ((c = fgetc(ifile)) != EOF) { + if (fputc(c, ofile) == EOF) + perrexit(2, "fputc on output"); + } + + if (ferror(ifile)) + perrexit(2, "fgetc on input"); + + fclose(ofile); + fclose(ifile); + + fprintf(stderr, "imgHdr.hdr_len = %lu\n", sizeof(imghdr)); + fprintf(stderr, "imgHdr.checksum = 0x%08x\n", cksum); + fprintf(stderr, "imgHdr.total_size = 0x%08x\n", bcnt); + fprintf(stderr, "imgHdr.kernel_size = 0x%08x\n", kernel); + fprintf(stderr, "imgHdr.header = %s\n", signature); + fprintf(stderr, "imgHdr.fw_ver = %s\n", version); + fprintf(stderr, "imgHdr.fw_reg = %s\n", region); + + return 0; +} diff --git a/tools/firmware-utils/src/mkdcs932.c b/tools/firmware-utils/src/mkdcs932.c new file mode 100644 index 00000000000..28c67aa3b30 --- /dev/null +++ b/tools/firmware-utils/src/mkdcs932.c @@ -0,0 +1,39 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License, + * version 2 as published by the Free Software Foundation. + * + * (C) John Crispin <blogic@openwrt.org> + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdint.h> +#include <unistd.h> +#include <errno.h> + +int main(int argc, char **argv) +{ + uint32_t t = 0, sum = 0x55aa55aa; + int fd; + + if ((argc != 2) || ((fd = open(argv[1], O_RDWR)) == -1)) { + fprintf(stderr, "Usage: %s input_file\n", *argv); + return -EINVAL; + } + + lseek(fd, -4, SEEK_END); + write(fd, &t, 4); + lseek(fd, 0, SEEK_SET); + + while (read(fd, &t, 4) > 0) + sum -= t; + + lseek(fd, -4, SEEK_END); + write(fd, &sum, 4); + close(fd); + + return 0; +} diff --git a/tools/firmware-utils/src/mkdhpimg.c b/tools/firmware-utils/src/mkdhpimg.c new file mode 100644 index 00000000000..e61d0425043 --- /dev/null +++ b/tools/firmware-utils/src/mkdhpimg.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016 FUKAUMI Naoki <naobsd@gmail.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <sys/stat.h> +#include <err.h> +#include <fcntl.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "buffalo-lib.h" + +#define DHP_HEADER_SIZE 20 + +static char *progname; + +static void +usage(void) +{ + + fprintf(stderr, "usage: %s <in> <out>\n", progname); + exit(EXIT_FAILURE); +} + +int +main(int argc, char *argv[]) +{ + struct stat in_st; + size_t size; + uint32_t crc; + int in, out; + uint8_t *buf; + + progname = argv[0]; + + if (argc != 3) + usage(); + + if ((in = open(argv[1], O_RDONLY)) == -1) + err(EXIT_FAILURE, "%s", argv[1]); + + if (fstat(in, &in_st) == -1) + err(EXIT_FAILURE, "%s", argv[1]); + + size = DHP_HEADER_SIZE + in_st.st_size; + + if ((buf = malloc(size)) == NULL) + err(EXIT_FAILURE, "malloc"); + + memset(buf, 0, DHP_HEADER_SIZE); + buf[0x0] = 0x62; + buf[0x1] = 0x67; + buf[0x2] = 0x6e; + buf[0xb] = 0xb1; + buf[0xc] = (size >> 24) & 0xff; + buf[0xd] = (size >> 16) & 0xff; + buf[0xe] = (size >> 8) & 0xff; + buf[0xf] = size & 0xff; + + read(in, &buf[DHP_HEADER_SIZE], in_st.st_size); + close(in); + + crc = buffalo_crc(buf, size); + buf[0x10] = (crc >> 24) & 0xff; + buf[0x11] = (crc >> 16) & 0xff; + buf[0x12] = (crc >> 8) & 0xff; + buf[0x13] = crc & 0xff; + + if ((out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) + err(EXIT_FAILURE, "%s", argv[2]); + write(out, buf, size); + close(out); + + free(buf); + + return EXIT_SUCCESS; +} diff --git a/tools/firmware-utils/src/mkdlinkfw-lib.c b/tools/firmware-utils/src/mkdlinkfw-lib.c new file mode 100644 index 00000000000..fcab8562319 --- /dev/null +++ b/tools/firmware-utils/src/mkdlinkfw-lib.c @@ -0,0 +1,172 @@ +/* + * mkdlinkfw + * + * Copyright (C) 2018 Paweł Dembicki <paweldembicki@gmail.com> + * + * This tool is based on mktplinkfw. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> /* for unlink() */ +#include <libgen.h> +#include <getopt.h> /* for getopt() */ +#include <stdarg.h> +#include <stdbool.h> +#include <endian.h> +#include <errno.h> +#include <time.h> +#include <sys/stat.h> +#include <zlib.h> /*for crc32 */ + +#include "mkdlinkfw-lib.h" + +extern char *progname; + +static unsigned char jffs2_eof_mark[4] = { 0xde, 0xad, 0xc0, 0xde }; + +uint32_t jboot_timestamp(void) +{ + time_t rawtime; + time(&rawtime); + return (((uint32_t) rawtime) - TIMESTAMP_MAGIC) >> 2; +} + +uint16_t jboot_checksum(uint16_t start_val, uint16_t *data, int size) +{ + uint32_t counter = start_val; + uint16_t *ptr = data; + + while (size > 1) { + counter += *ptr; + ++ptr; + while (counter >> 16) + counter = (uint16_t) counter + (counter >> 16); + size -= 2; + } + if (size > 0) { + counter += *(uint8_t *) ptr; + counter -= 0xFF; + } + while (counter >> 16) + counter = (uint16_t) counter + (counter >> 16); + return counter; +} + +int get_file_stat(struct file_info *fdata) +{ + struct stat st; + int res; + + if (fdata->file_name == NULL) + return 0; + + res = stat(fdata->file_name, &st); + if (res) { + ERRS("stat failed on %s", fdata->file_name); + return res; + } + + fdata->file_size = st.st_size; + return 0; +} + +int read_to_buf(const struct file_info *fdata, char *buf) +{ + FILE *f; + int ret = EXIT_FAILURE; + + f = fopen(fdata->file_name, "r"); + if (f == NULL) { + ERRS("could not open \"%s\" for reading", fdata->file_name); + goto out; + } + + errno = 0; + fread(buf, fdata->file_size, 1, f); + if (errno != 0) { + ERRS("unable to read from file \"%s\"", fdata->file_name); + goto out_close; + } + + ret = EXIT_SUCCESS; + + out_close: + fclose(f); + out: + return ret; +} + +int pad_jffs2(char *buf, int currlen, int maxlen) +{ + int len; + uint32_t pad_mask; + + len = currlen; + pad_mask = (4 * 1024) | (64 * 1024); /* EOF at 4KB and at 64KB */ + while ((len < maxlen) && (pad_mask != 0)) { + uint32_t mask; + int i; + + for (i = 10; i < 32; i++) { + mask = 1 << i; + if (pad_mask & mask) + break; + } + + len = ALIGN(len, mask); + + for (i = 10; i < 32; i++) { + mask = 1 << i; + if ((len & (mask - 1)) == 0) + pad_mask &= ~mask; + } + + for (i = 0; i < sizeof(jffs2_eof_mark); i++) + buf[len + i] = jffs2_eof_mark[i]; + + len += sizeof(jffs2_eof_mark); + } + + return len; +} + +int write_fw(const char *ofname, const char *data, int len) +{ + FILE *f; + int ret = EXIT_FAILURE; + + f = fopen(ofname, "w"); + if (f == NULL) { + ERRS("could not open \"%s\" for writing", ofname); + goto out; + } + + errno = 0; + fwrite(data, len, 1, f); + if (errno) { + ERRS("unable to write output file"); + goto out_flush; + } + + DBG("firmware file \"%s\" completed", ofname); + + ret = EXIT_SUCCESS; + + out_flush: + fflush(f); + fclose(f); + if (ret != EXIT_SUCCESS) + unlink(ofname); + out: + return ret; +} diff --git a/tools/firmware-utils/src/mkdlinkfw-lib.h b/tools/firmware-utils/src/mkdlinkfw-lib.h new file mode 100644 index 00000000000..d61124cb636 --- /dev/null +++ b/tools/firmware-utils/src/mkdlinkfw-lib.h @@ -0,0 +1,83 @@ +/* + * mkdlinkfw + * + * Copyright (C) 2018 Paweł Dembicki <paweldembicki@gmail.com> + * + * This tool is based on mktplinkfw. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#ifndef mkdlinkfw_lib_h +#define mkdlinkfw_lib_h + +#define AUH_MAGIC "DLK" +#define AUH_SIZE 80 +#define AUH_LVPS 0x01 +#define AUH_HDR_ID 0x4842 +#define AUH_HDR_VER 0x02 +#define AUH_SEC_ID 0x04 +#define AUH_INFO_TYPE 0x04 + +#define STAG_SIZE 16 +#define STAG_ID 0x04 +#define STAG_MAGIC 0x2B24 +#define STAG_CMARK_FACTORY 0xFF + +#define SCH2_SIZE 40 +#define SCH2_MAGIC 0x2124 +#define SCH2_VER 0x02 + +#define FLAT 0 +#define JZ 1 +#define GZIP 2 +#define LZMA 3 + +#define RAM_ENTRY_ADDR 0x80000000 +#define RAM_LOAD_ADDR 0x80000000 +#define JBOOT_SIZE 0x10000 + +#define ALL_HEADERS_SIZE (AUH_SIZE + STAG_SIZE + SCH2_SIZE) +#define MAX_HEADER_COUNTER 10 +#define TIMESTAMP_MAGIC 0x35016f00L + +#define FACTORY 0 +#define SYSUPGRADE 1 + +#define ALIGN(x, a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); }) + +#define ERR(fmt, ...) do { \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt "\n", \ + progname, ## __VA_ARGS__); \ +} while (0) + +#define ERRS(fmt, ...) do { \ + int save = errno; \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ + progname, ## __VA_ARGS__, strerror(save)); \ +} while (0) + +#define DBG(fmt, ...) do { \ + fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__); \ +} while (0) + +struct file_info { + char *file_name; /* name of the file */ + uint32_t file_size; /* length of the file */ +}; + +uint32_t jboot_timestamp(void); +uint16_t jboot_checksum(uint16_t start_val, uint16_t *data, int size); +int get_file_stat(struct file_info *fdata); +int read_to_buf(const struct file_info *fdata, char *buf); +int pad_jffs2(char *buf, int currlen, int maxlen); +int write_fw(const char *ofname, const char *data, int len); + +#endif /* mkdlinkfw_lib_h */ diff --git a/tools/firmware-utils/src/mkdlinkfw.c b/tools/firmware-utils/src/mkdlinkfw.c new file mode 100644 index 00000000000..87605004fe9 --- /dev/null +++ b/tools/firmware-utils/src/mkdlinkfw.c @@ -0,0 +1,665 @@ +/* + * mkdlinkfw + * + * Copyright (C) 2018 Paweł Dembicki <paweldembicki@gmail.com> + * + * This tool is based on mktplinkfw. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> /* for unlink() */ +#include <libgen.h> +#include <getopt.h> /* for getopt() */ +#include <stdarg.h> +#include <stdbool.h> +#include <endian.h> +#include <errno.h> +#include <sys/stat.h> +#include <zlib.h> /*for crc32 */ + +#include "mkdlinkfw-lib.h" + +/* ARM update header 2.0 + * used only in factory images to erase and flash selected area + */ +struct auh_header { + uint8_t rom_id[12]; /* 12-bit rom-id unique per router type */ + uint16_t derange; /* used for scramble header */ + uint16_t image_checksum; /* jboot_checksum of flashed data */ + + uint32_t space1; /* zeros */ + uint32_t space2; /* zeros */ + uint16_t space3; /* zerosu */ + uint8_t lpvs; /* must be 0x01 */ + uint8_t mbz; /* bust be 0 */ + uint32_t time_stamp; /* timestamp calculated in jboot way */ + + uint32_t erase_start; /* erase start address */ + uint32_t erase_length; /* erase length address */ + uint32_t data_offset; /* data start address */ + uint32_t data_length; /* data length address */ + + uint32_t space4; /* zeros */ + uint32_t space5; /* zeros */ + uint32_t space6; /* zeros */ + uint32_t space7; /* zeros */ + + uint16_t header_id; /* magic 0x4842 */ + uint16_t header_version; /* 0x02 for 2.0 */ + uint16_t space8; /* zeros */ + uint8_t section_id; /* section id */ + uint8_t image_info_type; /* (?) 0x04 in factory images */ + uint32_t image_info_offset; /* (?) zeros in factory images */ + uint16_t family_member; /* unique per router type */ + uint16_t header_checksum; /* negated jboot_checksum of header data */ +}; + +struct stag_header { /* used only of sch2 wrapped kernel data */ + uint8_t cmark; /* in factory 0xFF ,in sysuograde must be the same as id */ + uint8_t id; /* 0x04 */ + uint16_t magic; /* magic 0x2B24 */ + uint32_t time_stamp; /* timestamp calculated in jboot way */ + uint32_t image_length; /* lentgh of kernel + sch2 header */ + uint16_t image_checksum; /* negated jboot_checksum of sch2 + kernel */ + uint16_t tag_checksum; /* negated jboot_checksum of stag header data */ +}; + +struct sch2_header { /* used only in kernel partitions */ + uint16_t magic; /* magic 0x2124 */ + uint8_t cp_type; /* 0x00 for flat, 0x01 for jz, 0x02 for gzip, 0x03 for lzma */ + uint8_t version; /* 0x02 for sch2 */ + uint32_t ram_addr; /* ram entry address */ + uint32_t image_len; /* kernel image length */ + uint32_t image_crc32; /* kernel image crc */ + uint32_t start_addr; /* ram start address */ + uint32_t rootfs_addr; /* rootfs flash address */ + uint32_t rootfs_len; /* rootfls length */ + uint32_t rootfs_crc32; /* rootfs crc32 */ + uint32_t header_crc32; /* sch2 header crc32, durring calculation this area is replaced by zero */ + uint16_t header_length; /* sch2 header length: 0x28 */ + uint16_t cmd_line_length; /* cmd line length, known zeros */ +}; + +/* globals */ +static struct file_info inspect_info; +struct file_info kernel_info; +struct file_info rootfs_info; +struct file_info image_info; + +char *ofname; +char *progname; +uint32_t firmware_size; +uint16_t family_member; +char *rom_id[12] = { 0 }; + +char image_type; +int add_jffs2_eof; + +static void usage(int status) +{ + fprintf(stderr, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stderr, + "\n" + "Options:\n" + " -i <file> inspect given firmware file <file>\n" + " -f set family member id (hexval prefixed with 0x)\n" + " -F <file> read image and convert it to FACTORY\n" + " -k <file> read kernel image from the file <file>\n" + " -r <file> read rootfs image from the file <file>\n" + " -o <file> write output to the file <file>\n" + " -s <size> set firmware partition size\n" + " -m <version> set rom id to <version> (12-bit string val: \"DLK*********\")\n" + " -h show this screen\n"); + + exit(status); +} + +void print_auh_header(struct auh_header *printed_header) +{ + printf("\trom_id: %s\n" + "\tderange: 0x%04X\n" + "\timage_checksum: 0x%04X\n" + "\tspace1: 0x%08X\n" + "\tspace2: 0x%08X\n" + "\tspace3: 0x%04X\n" + "\tlpvs: 0x%02X\n" + "\tmbz: 0x%02X\n" + "\ttime_stamp: 0x%08X\n" + "\terase_start: 0x%08X\n" + "\terase_length: 0x%08X\n" + "\tdata_offset: 0x%08X\n" + "\tdata_length: 0x%08X\n" + "\tspace4: 0x%08X\n" + "\tspace5: 0x%08X\n" + "\tspace6: 0x%08X\n" + "\tspace7: 0x%08X\n" + "\theader_id: 0x%04X\n" + "\theader_version: 0x%02X\n" + "\tspace8: 0x%04X\n" + "\tsection_id: 0x%02X\n" + "\timage_info_type: 0x%02X\n" + "\timage_info_offset 0x%08X\n" + "\tfamily_member: 0x%04X\n" + "\theader_checksum: 0x%04X\n", + printed_header->rom_id, + printed_header->derange, + printed_header->image_checksum, + printed_header->space1, + printed_header->space2, + printed_header->space3, + printed_header->lpvs, + printed_header->mbz, + printed_header->time_stamp, + printed_header->erase_start, + printed_header->erase_length, + printed_header->data_offset, + printed_header->data_length, + printed_header->space4, + printed_header->space5, + printed_header->space6, + printed_header->space7, + printed_header->header_id, + printed_header->header_version, + printed_header->space8, + printed_header->section_id, + printed_header->image_info_type, + printed_header->image_info_offset, + printed_header->family_member, printed_header->header_checksum); +} + +void print_stag_header(struct stag_header *printed_header) +{ + printf("\tcmark: 0x%02X\n" + "\tid: 0x%02X\n" + "\tmagic: 0x%04X\n" + "\ttime_stamp: 0x%08X\n" + "\timage_length: 0x%04X\n" + "\timage_checksum: 0x%04X\n" + "\ttag_checksum: 0x%04X\n", + printed_header->cmark, + printed_header->id, + printed_header->magic, + printed_header->time_stamp, + printed_header->image_length, + printed_header->image_checksum, printed_header->tag_checksum); +} + +void print_sch2_header(struct sch2_header *printed_header) +{ + printf("\tmagic: 0x%04X\n" + "\tcp_type: 0x%02X\n" + "\tversion: 0x%02X\n" + "\tram_addr: 0x%08X\n" + "\timage_len: 0x%08X\n" + "\timage_crc32: 0x%08X\n" + "\tstart_addr: 0x%08X\n" + "\trootfs_addr: 0x%08X\n" + "\trootfs_len: 0x%08X\n" + "\trootfs_crc32: 0x%08X\n" + "\theader_crc32: 0x%08X\n" + "\theader_length: 0x%04X\n" + "\tcmd_line_length: 0x%04X\n", + printed_header->magic, + printed_header->cp_type, + printed_header->version, + printed_header->ram_addr, + printed_header->image_len, + printed_header->image_crc32, + printed_header->start_addr, + printed_header->rootfs_addr, + printed_header->rootfs_len, + printed_header->rootfs_crc32, + printed_header->header_crc32, + printed_header->header_length, printed_header->cmd_line_length); +} + +static int find_auh_headers(char *buf) +{ + char *tmp_buf = buf; + struct auh_header *tmp_header[MAX_HEADER_COUNTER]; + int header_counter = 0; + + int ret = EXIT_FAILURE; + + while (tmp_buf - buf <= inspect_info.file_size - AUH_SIZE) { + if (!memcmp(tmp_buf, AUH_MAGIC, 3)) { + if (((struct auh_header *)tmp_buf)->header_checksum == + (uint16_t) ~jboot_checksum(0, (uint16_t *) tmp_buf, + AUH_SIZE - 2)) { + uint16_t checksum = 0; + printf("Find proper AUH header at: 0x%lX!\n", + tmp_buf - buf); + tmp_header[header_counter] = + (struct auh_header *)tmp_buf; + checksum = + jboot_checksum(0, (uint16_t *) ((char *) + tmp_header + [header_counter] + + AUH_SIZE), + tmp_header + [header_counter]->data_length); + if (tmp_header[header_counter]->image_checksum + == checksum) + printf("Image checksum ok.\n"); + else + ERR("Image checksum incorrect! Stored: 0x%X Calculated: 0x%X\n", tmp_header[header_counter]->image_checksum, checksum); + header_counter++; + if (header_counter > MAX_HEADER_COUNTER) + break; + } + } + tmp_buf++; + } + + if (header_counter == 0) + ERR("Can't find proper AUH header!\n"); + else if (header_counter > MAX_HEADER_COUNTER) + ERR("To many AUH headers!\n"); + else { + for (int i = 0; i < header_counter; i++) { + printf("AUH %d:\n", i); + print_auh_header(tmp_header[i]); + } + + ret = EXIT_SUCCESS; + } + + return ret; +} + +static int check_stag_header(char *buf, struct stag_header *header) +{ + + int ret = EXIT_FAILURE; + + uint8_t cmark_tmp = header->cmark; + header->cmark = header->id; + + if (header->tag_checksum == + (uint16_t) ~jboot_checksum(0, (uint16_t *) header, + STAG_SIZE - 2)) { + uint16_t checksum = 0; + printf("Find proper STAG header at: 0x%lX!\n", + (char *)header - buf); + checksum = + jboot_checksum(0, (uint16_t *) ((char *)header + STAG_SIZE), + header->image_length); + if (header->image_checksum == checksum) { + printf("Image checksum ok.\n"); + header->cmark = cmark_tmp; + print_stag_header(header); + ret = EXIT_SUCCESS; + } else + ERR("Image checksum incorrect! Stored: 0x%X Calculated: 0x%X\n", header->image_checksum, checksum); + } else + ERR("STAG header checksum incorrect!"); + + header->cmark = cmark_tmp; + return ret; +} + +static int check_sch2_header(char *buf, struct sch2_header *header) +{ + + int ret = EXIT_FAILURE; + + uint32_t crc32_tmp = header->header_crc32; + header->header_crc32 = 0; + + if (crc32_tmp == crc32(0, (uint8_t *) header, header->header_length)) { + uint32_t crc32_val; + printf("Find proper SCH2 header at: 0x%lX!\n", + (char *)header - buf); + + crc32_val = + crc32(0, (uint8_t *) header + header->header_length, + header->image_len); + if (header->image_crc32 == crc32_val) { + printf("Kernel checksum ok.\n"); + + header->header_crc32 = crc32_tmp; + print_sch2_header(header); + ret = EXIT_SUCCESS; + } else + ERR("Kernel checksum incorrect! Stored: 0x%X Calculated: 0x%X\n", header->image_crc32, crc32_val); + + } else + ERR("SCH2 header checksum incorrect!"); + + header->header_crc32 = crc32_tmp; + return ret; +} + +static int inspect_fw(void) +{ + char *buf; + struct stag_header *stag_header_kernel; + struct sch2_header *sch2_header_kernel; + int ret = EXIT_FAILURE; + + buf = malloc(inspect_info.file_size); + if (!buf) { + ERR("no memory for buffer!\n"); + goto out; + } + + ret = read_to_buf(&inspect_info, buf); + if (ret) + goto out_free_buf; + + ret = find_auh_headers(buf); + if (ret) + goto out_free_buf; + + stag_header_kernel = (struct stag_header *)(buf + AUH_SIZE); + + ret = check_stag_header(buf, stag_header_kernel); + if (ret) + goto out_free_buf; + + sch2_header_kernel = (struct sch2_header *)(buf + AUH_SIZE + STAG_SIZE); + + ret = check_sch2_header(buf, sch2_header_kernel); + if (ret) + goto out_free_buf; + + out_free_buf: + free(buf); + out: + return ret; +} + +static int check_options(void) +{ + int ret; + + if (inspect_info.file_name) { + ret = get_file_stat(&inspect_info); + if (ret) + return ret; + + return 0; + } + + return 0; +} + +int fill_sch2(struct sch2_header *header, char *kernel_ptr, char *rootfs_ptr) +{ + + header->magic = SCH2_MAGIC; + header->cp_type = LZMA; + header->version = SCH2_VER; + header->ram_addr = RAM_LOAD_ADDR; + header->image_len = kernel_info.file_size; + header->image_crc32 = crc32(0, (uint8_t *) kernel_ptr, kernel_info.file_size); + header->start_addr = RAM_ENTRY_ADDR; + header->rootfs_addr = + JBOOT_SIZE + STAG_SIZE + SCH2_SIZE + kernel_info.file_size; + header->rootfs_len = rootfs_info.file_size; + header->rootfs_crc32 = crc32(0, (uint8_t *) rootfs_ptr, rootfs_info.file_size); + header->header_crc32 = 0; + header->header_length = SCH2_SIZE; + header->cmd_line_length = 0; + + header->header_crc32 = crc32(0, (uint8_t *) header, header->header_length); + + return EXIT_SUCCESS; +} + +int fill_stag(struct stag_header *header, uint32_t length) +{ + header->cmark = STAG_ID; + header->id = STAG_ID; + header->magic = STAG_MAGIC; + header->time_stamp = jboot_timestamp(); + header->image_length = length + SCH2_SIZE; + header->image_checksum = + jboot_checksum(0, (uint16_t *) ((char *)header + STAG_SIZE), + header->image_length); + header->tag_checksum = + ~jboot_checksum(0, (uint16_t *) header, STAG_SIZE - 2); + + if (image_type == FACTORY) + header->cmark = STAG_CMARK_FACTORY; + + return EXIT_SUCCESS; +}; + +int fill_auh(struct auh_header *header, uint32_t length) +{ + memcpy(header->rom_id, rom_id, 12); + header->derange = 0; + header->image_checksum = + jboot_checksum(0, (uint16_t *) ((char *)header + AUH_SIZE), length); + header->space1 = 0; + header->space2 = 0; + header->space3 = 0; + header->lpvs = AUH_LVPS; + header->mbz = 0; + header->time_stamp = jboot_timestamp(); + header->erase_start = JBOOT_SIZE; + header->erase_length = firmware_size; + header->data_offset = JBOOT_SIZE; + header->data_length = length; + header->space4 = 0; + header->space5 = 0; + header->space6 = 0; + header->space7 = 0; + header->header_id = AUH_HDR_ID; + header->header_version = AUH_HDR_VER; + header->space8 = 0; + header->section_id = AUH_SEC_ID; + header->image_info_type = AUH_INFO_TYPE; + header->image_info_offset = 0; + header->family_member = family_member; + header->header_checksum = + ~jboot_checksum(0, (uint16_t *) header, AUH_SIZE - 2); + + return EXIT_SUCCESS; +} + +int build_fw(void) +{ + char *buf; + char *kernel_ptr; + char *rootfs_ptr; + int ret = EXIT_FAILURE; + int writelen; + + struct stag_header *stag_header_kernel; + struct sch2_header *sch2_header_kernel; + + if (!kernel_info.file_name | !rootfs_info.file_name) + goto out; + + ret = get_file_stat(&kernel_info); + if (ret) + goto out; + ret = get_file_stat(&rootfs_info); + if (ret) + goto out; + + buf = malloc(firmware_size); + if (!buf) { + ERR("no memory for buffer\n"); + goto out; + } + + if (rootfs_info.file_size + kernel_info.file_size + ALL_HEADERS_SIZE > + firmware_size) { + ERR("data is bigger than firmware_size!\n"); + goto out; + } + + memset(buf, 0xff, firmware_size); + + stag_header_kernel = (struct stag_header *)buf; + + sch2_header_kernel = + (struct sch2_header *)((char *)stag_header_kernel + STAG_SIZE); + kernel_ptr = (char *)sch2_header_kernel + SCH2_SIZE; + + ret = read_to_buf(&kernel_info, kernel_ptr); + if (ret) + goto out_free_buf; + + rootfs_ptr = kernel_ptr + kernel_info.file_size; + + ret = read_to_buf(&rootfs_info, rootfs_ptr); + if (ret) + goto out_free_buf; + + writelen = rootfs_ptr + rootfs_info.file_size - buf; + + fill_sch2(sch2_header_kernel, kernel_ptr, rootfs_ptr); + fill_stag(stag_header_kernel, kernel_info.file_size); + + ret = write_fw(ofname, buf, writelen); + if (ret) + goto out_free_buf; + + ret = EXIT_SUCCESS; + + out_free_buf: + free(buf); + out: + return ret; +} + +int wrap_fw(void) +{ + char *buf; + char *image_ptr; + int ret = EXIT_FAILURE; + int writelen; + + struct auh_header *auh_header_kernel; + + if (!image_info.file_name) + goto out; + + ret = get_file_stat(&image_info); + if (ret) + goto out; + + buf = malloc(firmware_size); + if (!buf) { + ERR("no memory for buffer\n"); + goto out; + } + + if (image_info.file_size + AUH_SIZE > + firmware_size) { + ERR("data is bigger than firmware_size!\n"); + goto out; + } + if (!family_member) { + ERR("No family_member!\n"); + goto out; + } + if (!(rom_id[0])) { + ERR("No rom_id!\n"); + goto out; + } + memset(buf, 0xff, firmware_size); + + image_ptr = (char *)(buf + AUH_SIZE); + + ret = read_to_buf(&image_info, image_ptr); + if (ret) + goto out_free_buf; + + writelen = image_ptr + image_info.file_size - buf; + + auh_header_kernel = (struct auh_header *)buf; + fill_auh(auh_header_kernel, writelen - AUH_SIZE); + + ret = write_fw(ofname, buf, writelen); + if (ret) + goto out_free_buf; + + ret = EXIT_SUCCESS; + + out_free_buf: + free(buf); + out: + return ret; +} + +int main(int argc, char *argv[]) +{ + int ret = EXIT_FAILURE; + + progname = basename(argv[0]); + image_type = SYSUPGRADE; + family_member = 0; + firmware_size = 0; + + while (1) { + int c; + + c = getopt(argc, argv, "f:F:i:hk:m:o:r:s:"); + if (c == -1) + break; + + switch (c) { + case 'f': + sscanf(optarg, "0x%hx", &family_member); + break; + case 'F': + image_info.file_name = optarg; + image_type = FACTORY; + break; + case 'i': + inspect_info.file_name = optarg; + break; + case 'k': + kernel_info.file_name = optarg; + break; + case 'm': + if (strlen(optarg) == 12) + memcpy(rom_id, optarg, 12); + break; + case 'r': + rootfs_info.file_name = optarg; + break; + case 'o': + ofname = optarg; + break; + case 's': + sscanf(optarg, "0x%x", &firmware_size); + break; + default: + usage(EXIT_FAILURE); + break; + } + } + + ret = check_options(); + if (ret) + goto out; + + if (!inspect_info.file_name) { + if (image_type == FACTORY) + ret = wrap_fw(); + else + ret = build_fw(); + } + else + ret = inspect_fw(); + + out: + return ret; + +} diff --git a/tools/firmware-utils/src/mkdniimg.c b/tools/firmware-utils/src/mkdniimg.c index 7230f09d492..852b07dd9f6 100644 --- a/tools/firmware-utils/src/mkdniimg.c +++ b/tools/firmware-utils/src/mkdniimg.c @@ -43,7 +43,7 @@ static char *board_id; #define ERRS(fmt, ...) do { \ int save = errno; \ fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ + fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ progname, ## __VA_ARGS__, strerror(save)); \ } while (0) diff --git a/tools/firmware-utils/src/mkfwimage.c b/tools/firmware-utils/src/mkfwimage.c index a527014b551..d8d5239cc55 100644 --- a/tools/firmware-utils/src/mkfwimage.c +++ b/tools/firmware-utils/src/mkfwimage.c @@ -61,7 +61,7 @@ fw_layout_t fw_layout_data[] = { .name = "RSPRO", .kern_start = 0xbf030000, .kern_entry = 0x80060000, - .firmware_max_length= 0x00B00000, + .firmware_max_length= 0x00F00000, }, { .name = "LS-SR71", @@ -79,6 +79,12 @@ fw_layout_t fw_layout_data[] = { .name = "XM", .kern_start = 0x9f050000, .kern_entry = 0x80002000, + .firmware_max_length= 0x00760000, + }, + { + .name = "UBDEV01", + .kern_start = 0x9f050000, + .kern_entry = 0x80002000, .firmware_max_length= 0x006A0000, }, { .name = "", @@ -104,8 +110,6 @@ typedef struct part_data { #define OPTIONS "B:hv:m:o:r:k:" -static int debug = 0; - typedef struct image_info { char magic[16]; char version[256]; @@ -236,9 +240,9 @@ static int create_image_layout(const char* kernelfile, const char* rootfsfile, c fw_layout_t* p; p = &fw_layout_data[0]; - while ((strlen(p->name) != 0) && (strncmp(p->name, board_name, sizeof(board_name)) != 0)) + while (*p->name && (strcmp(p->name, board_name) != 0)) p++; - if (p->name == NULL) { + if (!*p->name) { printf("BUG! Unable to find default fw layout!\n"); exit(-1); } @@ -247,7 +251,7 @@ static int create_image_layout(const char* kernelfile, const char* rootfsfile, c strcpy(kernel->partition_name, "kernel"); kernel->partition_index = 1; kernel->partition_baseaddr = p->kern_start; - if ( (kernel->partition_length = filelength(kernelfile)) < 0) return (-1); + if ( (kernel->partition_length = filelength(kernelfile)) == (u_int32_t)-1) return (-1); kernel->partition_memaddr = p->kern_entry; kernel->partition_entryaddr = p->kern_entry; strncpy(kernel->filename, kernelfile, sizeof(kernel->filename)); @@ -263,8 +267,8 @@ static int create_image_layout(const char* kernelfile, const char* rootfsfile, c rootfs->partition_entryaddr = 0x00000000; strncpy(rootfs->filename, rootfsfile, sizeof(rootfs->filename)); -printf("kernel: %d 0x%08x\n", kernel->partition_length, kernel->partition_baseaddr); -printf("root: %d 0x%08x\n", rootfs->partition_length, rootfs->partition_baseaddr); + printf("kernel: %d 0x%08x\n", kernel->partition_length, kernel->partition_baseaddr); + printf("root: %d 0x%08x\n", rootfs->partition_length, rootfs->partition_baseaddr); im->part_count = 2; return 0; diff --git a/tools/firmware-utils/src/mkfwimage2.c b/tools/firmware-utils/src/mkfwimage2.c index ee09abba1ae..89a98051b43 100644 --- a/tools/firmware-utils/src/mkfwimage2.c +++ b/tools/firmware-utils/src/mkfwimage2.c @@ -197,6 +197,10 @@ int str2u32(char *arg, u_int32_t *val) return 0; } +#ifndef STRINGIFY +#define STRINGIFY2(X) #X +#define STRINGIFY(X) STRINGIFY2(X) +#endif static int image_layout_add_partition(const char *part_desc) { part_data_t *d; @@ -212,7 +216,7 @@ static int image_layout_add_partition(const char *part_desc) } d = &im.parts[im.part_count]; - t = sscanf(part_desc, "%15[a-zA-Z]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%256s", + t = sscanf(part_desc, "%15[-0-9a-zA-Z]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%"STRINGIFY(PATH_MAX)"s", d->partition_name, offset, length, diff --git a/tools/firmware-utils/src/mkheader_gemtek.c b/tools/firmware-utils/src/mkheader_gemtek.c new file mode 100644 index 00000000000..9e618efbadd --- /dev/null +++ b/tools/firmware-utils/src/mkheader_gemtek.c @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2014 Claudio Leite <leitec@staticky.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Builds a proper flash image for routers using some Gemtek + * OEM boards. These include the Airlink101 AR725W, the + * Asante SmartHub 600 (AWRT-600N), and Linksys WRT100/110. + * + * The resulting image is compatible with the factory firmware + * web upgrade and TFTP interface. + * + * To build: + * gcc -O2 -o mkheader_gemtek mkheader_gemtek.c -lz + * + * Claudio Leite <leitec@staticky.com> + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#include <zlib.h> /* for crc32() */ + +/* + * The header is in little-endian format. In case + * we are on a BE host, we need to swap binary + * values. + */ +#ifdef __APPLE__ +# include <libkern/OSByteOrder.h> +# define le32 OSSwapHostToLittleInt32 +#else +# if defined(__linux__) +# include <endian.h> +# if __BYTE_ORDER == __BIG_ENDIAN +# define CPU_BIG_ENDIAN +# endif +# else +# include <sys/endian.h> /* BSD's should have this */ +# if _BYTE_ORDER == _BIG_ENDIAN +# define CPU_BIG_ENDIAN +# endif +# endif +# ifdef CPU_BIG_ENDIAN +# define le32(x) (((x & 0xff000000) >> 24) | \ + ((x & 0x00ff0000) >> 8) | \ + ((x & 0x0000ff00) << 8) | \ + ((x & 0x000000ff) << 24)) +# else +# define le32(x) (x) +# endif +#endif + +struct gemtek_header { + uint8_t magic[4]; + uint8_t version[4]; + uint32_t product_id; + uint32_t imagesz; + uint32_t checksum; + uint32_t fast_checksum; + uint8_t build[4]; + uint8_t lang[4]; +}; + +#define HDRLEN sizeof(struct gemtek_header) + +struct machines { + char *desc; + char *id; + uint32_t maxsize; + struct gemtek_header header; +}; + +struct machines mach_def[] = { + {"Airlink101 AR725W", "ar725w", 0x340000, + {"GMTK", "1003", le32(0x03000001), 0, 0, + 0, "01\0\0", "EN\0\0"}}, + {"Asante AWRT-600N", "awrt600n", 0x340000, + {"A600", "1005", le32(0x03000001), 0, 0, + 0, "01\0\0", "EN\0\0"}}, + {"Linksys WRT100", "wrt100", 0x320000, + {"GMTK", "1007", le32(0x03040001), 0, 0, + 0, "2\0\0\0", "EN\0\0"}}, + {"Linksys WRT110", "wrt110", 0x320000, + {"GMTK", "1007", le32(0x03040001), 0, 0, + 0, "2\0\0\0", "EN\0\0"}}, + {0} +}; + +int +main(int argc, char *argv[]) +{ + unsigned long res, flen; + struct gemtek_header my_hdr; + FILE *f, *f_out; + int image_type = -1, index; + uint8_t *buf; + uint32_t crc; + + if (argc < 3) { + fprintf(stderr, "mkheader_gemtek <uImage> <webflash image> [machine ID]\n"); + fprintf(stderr, " where [machine ID] is one of:\n"); + for (index = 0; mach_def[index].desc != 0; index++) { + fprintf(stderr, " %-10s %s", mach_def[index].id, mach_def[index].desc); + if (index == 0) + fprintf(stderr, " (default)\n"); + else + fprintf(stderr, "\n"); + } + + exit(-1); + } + + if (argc == 4) { + for(index = 0; mach_def[index].id != 0; index++) { + if(strcmp(mach_def[index].id, argv[3]) == 0) { + image_type = index; + break; + } + } + + if(image_type == -1) { + fprintf(stderr, "\nERROR: invalid machine type\n"); + exit(-1); + } + } else + image_type = 0; + + printf("Opening %s...\n", argv[1]); + + f = fopen(argv[1], "r"); + if(!f) { + fprintf(stderr, "\nERROR: couldn't open input image\n"); + exit(-1); + } + + fseek(f, 0, SEEK_END); + flen = (unsigned long) ftell(f); + + printf(" %lu (0x%lX) bytes long\n", flen, flen); + + if (flen > mach_def[image_type].maxsize) { + fprintf(stderr, "\nERROR: image exceeds maximum compatible size\n"); + goto f_error; + } + + buf = malloc(flen + HDRLEN); + if (!buf) { + fprintf(stderr, "\nERROR: couldn't allocate buffer\n"); + goto f_error; + } + rewind(f); + res = fread(buf + HDRLEN, 1, flen, f); + if (res != flen) { + perror("Couldn't read entire file: fread()"); + goto f_error; + } + fclose(f); + + printf("\nCreating %s...\n", argv[2]); + + memcpy(&my_hdr, &mach_def[image_type].header, HDRLEN); + + printf(" Using %s magic\n", mach_def[image_type].desc); + + my_hdr.imagesz = le32(flen + HDRLEN); + memcpy(my_hdr.lang, "EN", 2); + + memcpy(buf, &my_hdr, HDRLEN); + + crc = crc32(0, buf, flen + HDRLEN); + printf(" CRC32: %08X\n", crc); + + my_hdr.checksum = le32(crc); + memcpy(buf, &my_hdr, HDRLEN); + + printf(" Writing...\n"); + + f_out = fopen(argv[2], "w"); + if(!f_out) { + fprintf(stderr, "\nERROR: couldn't open output image\n"); + exit(-1); + } + + fwrite(buf, 1, flen + HDRLEN, f_out); + + fclose(f_out); + + free(buf); + return 0; + +f_error: + fclose(f); + exit(-1); +} diff --git a/tools/firmware-utils/src/mkhilinkfw.c b/tools/firmware-utils/src/mkhilinkfw.c new file mode 100644 index 00000000000..55908e5caa7 --- /dev/null +++ b/tools/firmware-utils/src/mkhilinkfw.c @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2013 Jeff Kent <jeff@jkent.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * This tool encrypts and decrypts uImage formatted firmware for Hilink + * HLK-RM04 wireless modules. It will also truncate a dump of mtd6 and make + * it an image suitable for flashing via the stock firmware upgrade page. + * + * Build instructions: + * gcc -lcrypto hlkcrypt.c -o hlkcrypt + */ + +#include <arpa/inet.h> +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <openssl/des.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#define DES_KEY "H@L9K*(3" + +#ifndef min +#define min(a,b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; }) +#endif + +#define IH_MAGIC 0x27051956 +#define IH_NMLEN 32 +typedef struct image_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + uint8_t ih_name[IH_NMLEN]; /* Image Name */ +} image_header_t; + +static int temp_fd = -1; +static DES_key_schedule schedule; + +static void show_usage(const char *arg0); +static void exit_cleanup(void); +static void copy_file(int src, int dst); +static void do_encrypt(void *p, off_t len); +static void do_decrypt(void *p, off_t len); + + +int main(int argc, char **argv) +{ + int encrypt_opt = 0; + int decrypt_opt = 0; + int input_opt = 0; + int output_opt = 0; + char *input_filename = NULL; + char *output_filename = NULL; + + int input_fd; + int output_fd; + off_t file_len; + char *p; + char buf[sizeof(image_header_t) + 3]; + image_header_t *header; + + while (1) { + static struct option long_options[] = { + {"encrypt", no_argument, 0, 'e'}, + {"decrypt", no_argument, 0, 'd'}, + {"input", required_argument, 0, 'i'}, + {"output", required_argument, 0, 'o'}, + {0, 0, 0, 0 } + }; + int option_index = 0; + int c = getopt_long(argc, argv, "dei:o:", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'd': + decrypt_opt++; + if (decrypt_opt > 1) { + fprintf(stderr, "%s: decrypt may only be specified once\n", + argv[0]); + show_usage(argv[0]); + } + break; + + case 'e': + encrypt_opt++; + if (encrypt_opt > 1) { + fprintf(stderr, "%s: encrypt may only be specified once\n", + argv[0]); + show_usage(argv[0]); + } + break; + + case 'i': + input_opt++; + if (input_opt > 1) { + fprintf(stderr, "%s: only one input file may be specified\n", + argv[0]); + show_usage(argv[0]); + } + if (strcmp("-", optarg) != 0) { + input_filename = optarg; + } + break; + + case 'o': + output_opt++; + if (output_opt > 1) { + fprintf(stderr, "%s: only one output file may be specified\n", + argv[0]); + show_usage(argv[0]); + } + if (strcmp("-", optarg) != 0) { + output_filename = optarg; + } + break; + + case '?': + exit(-1); + + default: + abort(); + } + } + + if (decrypt_opt && encrypt_opt) { + fprintf(stderr, "%s: decrypt and encrypt may not be used together\n", + argv[0]); + show_usage(argv[0]); + } + + if (!decrypt_opt && !encrypt_opt) { + fprintf(stderr, "%s: neither decrypt or encrypt were specified\n", + argv[0]); + show_usage(argv[0]); + } + + temp_fd = fileno(tmpfile()); + if (temp_fd < 0) { + fprintf(stderr, "Can't create temporary file\n"); + exit(EXIT_FAILURE); + } + + atexit(exit_cleanup); + DES_set_key_unchecked((const_DES_cblock *)DES_KEY, &schedule); + + if (input_filename) { + input_fd = open(input_filename, O_RDONLY); + if (input_fd < 0) { + fprintf(stderr, "Can't open %s for reading: %s\n", input_filename, + strerror(errno)); + exit(EXIT_FAILURE); + } + copy_file(input_fd, temp_fd); + close(input_fd); + } + else { + copy_file(STDIN_FILENO, temp_fd); + } + + file_len = lseek(temp_fd, 0, SEEK_CUR); + if (file_len < 64) { + fprintf(stderr, "Not enough data\n"); + exit(EXIT_FAILURE); + } + + p = mmap(0, file_len, PROT_READ|PROT_WRITE, MAP_SHARED, temp_fd, 0); + if (p == MAP_FAILED) { + fprintf(stderr, "mmap failed: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + if (encrypt_opt) { + header = (image_header_t *)p; + off_t len = min(file_len, + ntohl(header->ih_size) + sizeof(image_header_t)); + if (ntohl(header->ih_magic) != IH_MAGIC) { + fprintf(stderr, "Header magic incorrect: " + "expected 0x%08X, got 0x%08X\n", + IH_MAGIC, ntohl(header->ih_magic)); + munmap(p, file_len); + exit(EXIT_FAILURE); + } + do_encrypt(p, len); + munmap(p, file_len); + if (len != file_len) { + if (ftruncate(temp_fd, len) < 0) { + fprintf(stderr, "ftruncate failed: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + } + } + + if (decrypt_opt) { + off_t header_len = min(file_len, sizeof(image_header_t) + 3); + memcpy(buf, p, header_len); + do_decrypt(buf, header_len); + header = (image_header_t *)buf; + if (ntohl(header->ih_magic) != IH_MAGIC) { + fprintf(stderr, "Header magic incorrect: " + "expected 0x%08X, got 0x%08X\n", + IH_MAGIC, ntohl(header->ih_magic)); + exit(EXIT_FAILURE); + } + do_decrypt(p, file_len); + munmap(p, file_len); + } + + lseek(temp_fd, 0, SEEK_SET); + if (output_filename) { + output_fd = creat(output_filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + if (output_fd < 0) { + fprintf(stderr, "Can't open %s for writing: %s\n", + output_filename, strerror(errno)); + exit(EXIT_FAILURE); + } + copy_file(temp_fd, output_fd); + close(output_fd); + } + else { + copy_file(temp_fd, STDOUT_FILENO); + } + + exit(EXIT_SUCCESS); + return 0; +} + +static void show_usage(const char *arg0) +{ + fprintf(stderr, "usage: %s -d|-e [-i FILE] [-o FILE]\n\n", arg0); + fprintf(stderr, "%-15s %s\n", "-d, --decrypt", "decrypt data"); + fprintf(stderr, "%-15s %s\n", "-e, --encrypt", "encrypt data"); + fprintf(stderr, "%-15s %s\n", "-i, --input", "intput file (defaults to stdin)"); + fprintf(stderr, "%-15s %s\n", "-o, --output", "output file (defaults to stdout)"); + exit(-1); +} + +static void exit_cleanup(void) +{ + if (temp_fd >= 0) { + close(temp_fd); + } +} + +static void copy_file(int src, int dst) +{ + char buf[4096]; + ssize_t size; + + while ((size = read(src, buf, 4096)) > 0) { + write(dst, buf, size); + } +} + +static void do_encrypt(void *p, off_t len) +{ + DES_cblock *pblock; + int num_blocks; + + num_blocks = len / 8; + pblock = (DES_cblock *) p; + while (num_blocks--) { + DES_ecb_encrypt(pblock, pblock, &schedule, DES_ENCRYPT); + pblock++; + } + + num_blocks = (len - 3) / 8; + pblock = (DES_cblock *) (p + 3); + while (num_blocks--) { + DES_ecb_encrypt(pblock, pblock, &schedule, DES_ENCRYPT); + pblock++; + } +} + +static void do_decrypt(void *p, off_t len) +{ + DES_cblock *pblock; + int num_blocks; + + num_blocks = (len - 3) / 8; + pblock = (DES_cblock *) (p + 3); + while (num_blocks--) { + DES_ecb_encrypt(pblock, pblock, &schedule, DES_DECRYPT); + pblock++; + } + + num_blocks = len / 8; + pblock = (DES_cblock *) p; + while (num_blocks--) { + DES_ecb_encrypt(pblock, pblock, &schedule, DES_DECRYPT); + pblock++; + } +} diff --git a/tools/firmware-utils/src/mkmerakifw-old.c b/tools/firmware-utils/src/mkmerakifw-old.c new file mode 100644 index 00000000000..05317c2a5b4 --- /dev/null +++ b/tools/firmware-utils/src/mkmerakifw-old.c @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2015 Thomas Hebb <tommyhebb@gmail.com> + * Copyright (C) 2016 Christian Lamparter <chunkeey@googlemail.com> + * + * The format of the header this tool generates was first documented by + * Chris Blake <chrisrblake93 (at) gmail.com> in a shell script of the + * same purpose. I have created this reimplementation at his request. The + * original script can be found at: + * <https://github.com/riptidewave93/meraki-partbuilder> + * + * Support for the old header format, which is used by the Cisco Z1 AP + * has been reverse engineered from the nandloader's nand_load_bk function. + * The original code is part of Cisco's GPL code and can be found at: + * <https://github.com/riptidewave93/meraki-linux> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <libgen.h> +#include <endian.h> +#include <getopt.h> +#include <errno.h> +#include <arpa/inet.h> + +#define PADDING_BYTE 0xff + +#define HDR_LENGTH 0x00000020 +#define HDR_OFF_MAGIC1 0 +#define HDR_OFF_LOAD_ADDR 4 +#define HDR_OFF_IMAGELEN 8 +#define HDR_OFF_ENTRY 12 +#define HDR_OFF_CHECKSUM 16 +#define HDR_OFF_FILLER0 20 +#define HDR_OFF_FILLER1 24 +#define HDR_OFF_FILLER2 28 + +struct board_info { + char *id; + char *description; + uint32_t magic; + uint32_t imagelen; + uint32_t load_addr; + uint32_t entry; +}; + +/* + * Globals + */ +static char *progname; +static bool strip_padding; + +static char *board_id; +static const struct board_info *board; + +static const struct board_info boards[] = { + { + .id = "z1", + .description = "Meraki Z1 Access Point", + .magic = 0x4d495053, + .imagelen = 0x007e0000, + .load_addr = 0x80060000, + .entry = 0x80060000 + }, { + /* terminating entry */ + } +}; + +/* + * Message macros + */ +#define ERR(fmt, ...) do { \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt "\n", \ + progname, ## __VA_ARGS__); \ +} while (0) + +#define ERRS(fmt, ...) do { \ + int save = errno; \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt "\n", \ + progname, ## __VA_ARGS__, strerror(save)); \ +} while (0) + +static const struct board_info *find_board(const char *id) +{ + const struct board_info *ret; + const struct board_info *board; + + ret = NULL; + for (board = boards; board->id != NULL; board++) { + if (strcasecmp(id, board->id) == 0) { + ret = board; + break; + } + } + + return ret; +} + +static void usage(int status) +{ + FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; + const struct board_info *board; + + fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stream, +"\n" +"Options:\n" +" -B <board> create image for the board specified with <board>\n" +" -i <file> read kernel image from the file <file>\n" +" -o <file> write output to the file <file>\n" +" -s strip padding from the end of the image\n" +" -h show this screen\n" + ); + + fprintf(stream, "\nBoards:\n"); + for (board = boards; board->id != NULL; board++) + fprintf(stream, " %-16s%s\n", board->id, board->description); + + exit(status); +} + +static void writel(unsigned char *buf, size_t offset, uint32_t value) +{ + value = htonl(value); + memcpy(buf + offset, &value, sizeof(uint32_t)); +} + +static const uint32_t crc32_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +static inline uint32_t crc32_accumulate_8(const uint32_t crc, const uint8_t ch) +{ + return crc32_table[(crc ^ ch) & 0xff] ^ (crc >> 8); +} + +static void crc32_csum(uint8_t *buf, const size_t len) +{ + uint32_t crc; + size_t i; + + crc = ~0; + for (i = 0; i < len; i += 4) { + crc = crc32_accumulate_8(crc, buf[i + 3]); + crc = crc32_accumulate_8(crc, buf[i + 2]); + crc = crc32_accumulate_8(crc, buf[i + 1]); + crc = crc32_accumulate_8(crc, buf[i]); + } + crc = ~crc; + + writel(buf, HDR_OFF_CHECKSUM, crc); +} + + +static int meraki_build_hdr(const struct board_info *board, const size_t klen, + FILE *out, FILE *in) +{ + unsigned char *kernel; + unsigned char *buf; + size_t buflen; + size_t kspace; + + size_t rc; + buflen = board->imagelen; + kspace = buflen - HDR_LENGTH; + + if (klen > kspace) { + ERR("kernel file is too big - max size: 0x%08lX\n", kspace); + return EXIT_FAILURE; + } + + /* If requested, resize buffer to remove padding */ + if (strip_padding) + buflen = klen + HDR_LENGTH; + + /* Allocate and initialize buffer for final image */ + buf = malloc(buflen); + if (buf == NULL) { + ERRS("no memory for buffer: %s\n"); + return EXIT_FAILURE; + } + memset(buf, PADDING_BYTE, buflen); + + /* Load kernel */ + kernel = buf + HDR_LENGTH; + fread(kernel, klen, 1, in); + + /* Write magic values and filler */ + writel(buf, HDR_OFF_MAGIC1, board->magic); + writel(buf, HDR_OFF_FILLER0, 0); + writel(buf, HDR_OFF_FILLER1, 0); + writel(buf, HDR_OFF_FILLER2, 0); + + /* Write load and kernel entry point address */ + writel(buf, HDR_OFF_LOAD_ADDR, board->load_addr); + writel(buf, HDR_OFF_ENTRY, board->entry); + + /* Write header and image length */ + writel(buf, HDR_OFF_IMAGELEN, klen); + + /* this gets replaced later, after the checksum has been calculated */ + writel(buf, HDR_OFF_CHECKSUM, 0); + + /* Write checksum */ + crc32_csum(buf, klen + HDR_LENGTH); + + rc = fwrite(buf, buflen, 1, out); + + free(buf); + + return rc == 1 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +int main(int argc, char *argv[]) +{ + int ret = EXIT_FAILURE; + char *ofname = NULL, *ifname = NULL; + FILE *out, *in; + size_t klen; + + progname = basename(argv[0]); + + while (1) { + int c; + + c = getopt(argc, argv, "B:i:o:sh"); + if (c == -1) + break; + + switch (c) { + case 'B': + board_id = optarg; + break; + case 'i': + ifname = optarg; + break; + case 'o': + ofname = optarg; + break; + case 's': + strip_padding = true; + break; + case 'h': + usage(EXIT_SUCCESS); + break; + default: + usage(EXIT_FAILURE); + break; + } + } + + if (board_id == NULL) { + ERR("no board specified"); + goto err; + } + + board = find_board(board_id); + if (board == NULL) { + ERR("unknown board \"%s\"", board_id); + goto err; + } + + if (ifname == NULL) { + ERR("no input file specified"); + goto err; + } + + if (ofname == NULL) { + ERR("no output file specified"); + goto err; + } + + in = fopen(ifname, "r"); + if (in == NULL) { + ERRS("could not open \"%s\" for reading: %s", ifname); + goto err; + } + + /* Get kernel length */ + fseek(in, 0, SEEK_END); + klen = ftell(in); + rewind(in); + + out = fopen(ofname, "w"); + if (out == NULL) { + ERRS("could not open \"%s\" for writing: %s", ofname); + goto err_close_in; + } + + ret = meraki_build_hdr(board, klen, out, in); + fclose(out); + +err_close_in: + fclose(in); + +err: + return ret; +} diff --git a/tools/firmware-utils/src/mkmerakifw.c b/tools/firmware-utils/src/mkmerakifw.c new file mode 100644 index 00000000000..1a50f1658f7 --- /dev/null +++ b/tools/firmware-utils/src/mkmerakifw.c @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2015 Thomas Hebb <tommyhebb@gmail.com> + * + * The format of the header this tool generates was first documented by + * Chris Blake <chrisrblake93 (at) gmail.com> in a shell script of the + * same purpose. I have created this reimplementation at his request. The + * original script can be found at: + * <https://github.com/riptidewave93/meraki-partbuilder> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <libgen.h> +#include <getopt.h> +#include <errno.h> +#include <arpa/inet.h> + +#include "sha1.h" + +#define PADDING_BYTE 0xff + +#define HDR_LENGTH 0x00000400 +#define HDR_OFF_MAGIC1 0 +#define HDR_OFF_HDRLEN 4 +#define HDR_OFF_IMAGELEN 8 +#define HDR_OFF_CHECKSUM 12 +#define HDR_OFF_MAGIC2 32 +#define HDR_OFF_MAGIC3 36 +#define HDR_OFF_STATICHASH 40 +#define HDR_OFF_KERNEL_OFFSET 40 +#define HDR_OFF_RAMDISK_OFFSET 44 +#define HDR_OFF_FDT_OFFSET 48 +#define HDR_OFF_UNKNOWN_OFFSET 52 + +struct board_info { + uint32_t magic1; + uint32_t magic2; + uint32_t magic3; + uint32_t imagelen; + union { + unsigned char statichash[20]; + struct { + uint32_t kernel_offset; + uint32_t ramdisk_offset; + uint32_t fdt_offset; + uint32_t unknown_offset; + } mx60; + } u; + char *id; + char *description; +}; + +/* + * Globals + */ +static char *progname; + +static char *board_id; +static const struct board_info *board; + +static const struct board_info boards[] = { + { + .id = "mr18", + .description = "Meraki MR18 Access Point", + .magic1 = 0x8e73ed8a, + .magic2 = 0x8e73ed8a, + .imagelen = 0x00800000, + .u.statichash = {0xda, 0x39, 0xa3, 0xee, 0x5e, + 0x6b, 0x4b, 0x0d, 0x32, 0x55, + 0xbf, 0xef, 0x95, 0x60, 0x18, + 0x90, 0xaf, 0xd8, 0x07, 0x09}, + }, { + .id = "mr24", + .description = "Meraki MR24 Access Point", + .magic1 = 0x8e73ed8a, + .magic2 = 0x8e73ed8a, + .imagelen = 0x00800000, + .u.statichash = {0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff}, + }, { + .id = "mx60", + .description = "Meraki MX60/MX60W Security Appliance", + .magic1 = 0x8e73ed8a, + .magic2 = 0xa1f0beef, /* Enables use of load addr in statichash */ + .magic3 = 0x00060001, /* This goes along with magic2 */ + .imagelen = 0x3fd00000, + /* The static hash below does the following: + * 1st Row: Kernel Offset + * 2nd Row: Ramdisk Offset + * 3rd Row: FDT Offset + * 4th Row: ? Unused/Unknown ? + * 5th Row: ? Unused/Unknown ? + */ + .u.mx60 = { + .kernel_offset = 0x10000, + .ramdisk_offset = 0x3FFC00, + .fdt_offset = 0x0400, + .unknown_offset = 0x0400, + }, + }, { + /* terminating entry */ + } +}; + +/* + * Message macros + */ +#define ERR(fmt, ...) do { \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt "\n", \ + progname, ## __VA_ARGS__); \ +} while (0) + +#define ERRS(fmt, ...) do { \ + int save = errno; \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt "\n", \ + progname, ## __VA_ARGS__, strerror(save)); \ +} while (0) + +static const struct board_info *find_board(const char *id) +{ + const struct board_info *ret; + const struct board_info *board; + + ret = NULL; + for (board = boards; board->id != NULL; board++) { + if (strcasecmp(id, board->id) == 0) { + ret = board; + break; + } + } + + return ret; +} + +static void usage(int status) +{ + FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; + const struct board_info *board; + + fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stream, +"\n" +"Options:\n" +" -B <board> create image for the board specified with <board>\n" +" -i <file> read kernel image from the file <file>\n" +" -o <file> write output to the file <file>\n" +" -s strip padding from the end of the image\n" +" -h show this screen\n" + ); + + fprintf(stream, "\nBoards:\n"); + for (board = boards; board->id != NULL; board++) + fprintf(stream, " %-16s%s\n", board->id, board->description); + + exit(status); +} + +void writel(unsigned char *buf, size_t offset, uint32_t value) +{ + value = htonl(value); + memcpy(buf + offset, &value, sizeof(uint32_t)); +} + +int main(int argc, char *argv[]) +{ + int ret = EXIT_FAILURE; + long klen; + size_t kspace; + unsigned char *kernel; + size_t buflen; + unsigned char *buf; + bool strip_padding = false; + char *ofname = NULL, *ifname = NULL; + FILE *out, *in; + + progname = basename(argv[0]); + + while (1) { + int c; + + c = getopt(argc, argv, "B:i:o:sh"); + if (c == -1) + break; + + switch (c) { + case 'B': + board_id = optarg; + break; + case 'i': + ifname = optarg; + break; + case 'o': + ofname = optarg; + break; + case 's': + strip_padding = true; + break; + case 'h': + usage(EXIT_SUCCESS); + break; + default: + usage(EXIT_FAILURE); + break; + } + } + + if (board_id == NULL) { + ERR("no board specified"); + goto err; + } + + board = find_board(board_id); + if (board == NULL) { + ERR("unknown board \"%s\"", board_id); + goto err; + } + + if (ifname == NULL) { + ERR("no input file specified"); + goto err; + } + + if (ofname == NULL) { + ERR("no output file specified"); + goto err; + } + + in = fopen(ifname, "r"); + if (in == NULL) { + ERRS("could not open \"%s\" for reading: %s", ifname); + goto err; + } + + buflen = board->imagelen; + kspace = buflen - HDR_LENGTH; + + /* Get kernel length */ + fseek(in, 0, SEEK_END); + klen = ftell(in); + rewind(in); + + if (klen > kspace) { + ERR("file \"%s\" is too big - max size: 0x%08lX\n", + ifname, kspace); + goto err_close_in; + } + + /* If requested, resize buffer to remove padding */ + if (strip_padding) + buflen = klen + HDR_LENGTH; + + /* Allocate and initialize buffer for final image */ + buf = malloc(buflen); + if (buf == NULL) { + ERRS("no memory for buffer: %s\n"); + goto err_close_in; + } + memset(buf, PADDING_BYTE, buflen); + + /* Load kernel */ + kernel = buf + HDR_LENGTH; + fread(kernel, klen, 1, in); + + /* Write magic values */ + writel(buf, HDR_OFF_MAGIC1, board->magic1); + writel(buf, HDR_OFF_MAGIC2, board->magic2); + writel(buf, HDR_OFF_MAGIC3, board->magic3); + + /* Write header and image length */ + writel(buf, HDR_OFF_HDRLEN, HDR_LENGTH); + writel(buf, HDR_OFF_IMAGELEN, klen); + + /* Write checksum and static hash */ + sha1_csum(kernel, klen, buf + HDR_OFF_CHECKSUM); + + switch (board->magic2) { + case 0xa1f0beef: + writel(buf, HDR_OFF_KERNEL_OFFSET, board->u.mx60.kernel_offset); + writel(buf, HDR_OFF_RAMDISK_OFFSET, board->u.mx60.ramdisk_offset); + writel(buf, HDR_OFF_FDT_OFFSET, board->u.mx60.fdt_offset), + writel(buf, HDR_OFF_UNKNOWN_OFFSET, board->u.mx60.unknown_offset); + break; + + case 0x8e73ed8a: + memcpy(buf + HDR_OFF_STATICHASH, board->u.statichash, 20); + break; + } + + /* Save finished image */ + out = fopen(ofname, "w"); + if (out == NULL) { + ERRS("could not open \"%s\" for writing: %s", ofname); + goto err_free; + } + fwrite(buf, buflen, 1, out); + + ret = EXIT_SUCCESS; + + fclose(out); + +err_free: + free(buf); + +err_close_in: + fclose(in); + +err: + return ret; +} diff --git a/tools/firmware-utils/src/mkplanexfw.c b/tools/firmware-utils/src/mkplanexfw.c index 1bdccb7c026..0b71f80438f 100644 --- a/tools/firmware-utils/src/mkplanexfw.c +++ b/tools/firmware-utils/src/mkplanexfw.c @@ -82,7 +82,7 @@ static struct board_info boards[] = { #define ERRS(fmt, ...) do { \ int save = errno; \ fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ + fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ progname, ## __VA_ARGS__, strerror(save)); \ } while (0) diff --git a/tools/firmware-utils/src/mkporayfw.c b/tools/firmware-utils/src/mkporayfw.c new file mode 100644 index 00000000000..6ec4f320d93 --- /dev/null +++ b/tools/firmware-utils/src/mkporayfw.c @@ -0,0 +1,791 @@ +/* + * Builder/viewer/extractor utility for Poray firmware image files + * + * Copyright (C) 2013 Michel Stempin <michel.stempin@wanadoo.fr> + * Copyright (C) 2013 Felix Kaechele <felix@fetzig.org> + * Copyright (C) 2013 <admin@openschemes.com> + * + * This tool is based on: + * TP-Link firmware upgrade tool. + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> + * + * Itself based on: + * TP-Link WR941 V2 firmware checksum fixing tool. + * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> +#include <libgen.h> +#include <getopt.h> +#include <stdarg.h> +#include <errno.h> +#include <sys/stat.h> +#include <arpa/inet.h> +#include <netinet/in.h> + +#if (__BYTE_ORDER == __BIG_ENDIAN) +# define HOST_TO_BE32(x) (x) +# define BE32_TO_HOST(x) (x) +# define HOST_TO_LE32(x) bswap_32(x) +# define LE32_TO_HOST(x) bswap_32(x) +#else +# define HOST_TO_BE32(x) bswap_32(x) +# define BE32_TO_HOST(x) bswap_32(x) +# define HOST_TO_LE32(x) (x) +# define LE32_TO_HOST(x) (x) +#endif + +/* Fixed header flags */ +#define HEADER_FLAGS 0x020e0000 + +/* Recognized Hardware ID magic */ +#define HWID_HAME_MPR_A1_L8 0x32473352 +#define HWID_PORAY_R50B 0x31353033 +#define HWID_PORAY_R50D 0x33353033 +#define HWID_PORAY_R50E 0x34353033 +#define HWID_PORAY_M3 0x31353335 +#define HWID_PORAY_M4 0x32353335 +#define HWID_PORAY_Q3 0x33353335 +#define HWID_PORAY_X5_X6 0x35353335 +#define HWID_PORAY_X8 0x36353335 +#define HWID_PORAY_X1 0x38353335 +#define HWID_NEXX_WT1520 0x30353332 +#define HWID_NEXX_WT3020 0x30323033 +#define HWID_A5_V11 0x32473352 + +/* Recognized XOR obfuscation keys */ +#define KEY_HAME 0 +#define KEY_PORAY_1 1 +#define KEY_PORAY_2 2 +#define KEY_PORAY_3 3 +#define KEY_PORAY_4 4 +#define KEY_NEXX_1 5 +#define KEY_NEXX_2 6 +#define KEY_A5_V11 7 + +/* XOR key length */ +#define KEY_LEN 15 + +struct file_info { + char *file_name; /* Name of the file */ + uint32_t file_size; /* Length of the file */ +}; + +struct fw_header { + uint32_t hw_id; /* Hardware id */ + uint32_t firmware_len; /* Firmware data length */ + uint32_t flags; /* Header flags */ + uint8_t pad[16]; +} __attribute__ ((packed)); + +struct flash_layout { + char *id; + uint32_t fw_max_len; +}; + +struct board_info { + char *id; + uint32_t hw_id; + char *layout_id; + uint32_t key; +}; + +/* + * Globals + */ +static char *ofname; +static char *progname; + +static char *board_id; +static struct board_info *board; +static char *layout_id; +static struct flash_layout *layout; +static char *opt_hw_id; +static uint32_t hw_id; +static struct file_info firmware_info; +static uint32_t firmware_len = 0; + +static int inspect = 0; +static int extract = 0; + +static uint8_t key[][KEY_LEN] = { + {0xC8, 0x3C, 0x3A, 0x93, 0xA2, 0x95, 0xC3, 0x63, 0x48, 0x45, 0x58, 0x09, 0x12, 0x03, 0x08}, + {0x89, 0x6B, 0x5A, 0x93, 0x92, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0xE6, 0xC7}, + {0xC9, 0x1C, 0x3A, 0x93, 0x92, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0xE6, 0xC7}, + {0x19, 0x1B, 0x3A, 0x93, 0x92, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0xE6, 0xC7}, + {0x79, 0x7B, 0x7A, 0x93, 0x92, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0xE6, 0xC7}, + {0x19, 0x1C, 0x4A, 0x93, 0x96, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0x16, 0xC6}, + {0x39, 0x1C, 0x4A, 0x93, 0x96, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0x16, 0xC6}, + {0xC8, 0x3C, 0x3A, 0x93, 0xA2, 0x95, 0xC3, 0x63, 0x48, 0x45, 0x58, 0x09, 0x20, 0x11, 0x08}, +}; + +static struct flash_layout layouts[] = { + { + .id = "4M", + .fw_max_len = 0x3c0000, + }, { + .id = "8M", + .fw_max_len = 0x7c0000, + }, { + /* terminating entry */ + } +}; + +static struct board_info boards[] = { + { + .id = "A5-V11", + .hw_id = HWID_A5_V11, + .layout_id = "4M", + .key = KEY_A5_V11, + }, { + .id = "MPR-A1", + .hw_id = HWID_HAME_MPR_A1_L8, + .layout_id = "4M", + .key = KEY_HAME, + }, { + .id = "MPR-L8", + .hw_id = HWID_HAME_MPR_A1_L8, + .layout_id = "4M", + .key = KEY_HAME, + }, { + .id = "R50B", + .hw_id = HWID_PORAY_R50B, + .layout_id = "4M", + .key = KEY_PORAY_2, + }, { + .id = "R50D", + .hw_id = HWID_PORAY_R50D, + .layout_id = "4M", + .key = KEY_PORAY_3, + }, { + .id = "R50E", + .hw_id = HWID_PORAY_R50E, + .layout_id = "4M", + .key = KEY_PORAY_4, + }, { + .id = "M3", + .hw_id = HWID_PORAY_M3, + .layout_id = "4M", + .key = KEY_PORAY_1, + }, { + .id = "M4", + .hw_id = HWID_PORAY_M4, + .layout_id = "4M", + .key = KEY_PORAY_1, + }, { + .id = "Q3", + .hw_id = HWID_PORAY_Q3, + .layout_id = "4M", + .key = KEY_PORAY_1, + }, { + .id = "X5 or X6", + .hw_id = HWID_PORAY_X5_X6, + .layout_id = "8M", + .key = KEY_PORAY_1, + }, { + .id = "X5", + .hw_id = HWID_PORAY_X5_X6, + .layout_id = "8M", + .key = KEY_PORAY_1, + }, { + .id = "X6", + .hw_id = HWID_PORAY_X5_X6, + .layout_id = "8M", + .key = KEY_PORAY_1, + }, { + .id = "X8", + .hw_id = HWID_PORAY_X8, + .layout_id = "8M", + .key = KEY_PORAY_1, + }, { + .id = "X1", + .hw_id = HWID_PORAY_X1, + .layout_id = "8M", + .key = KEY_PORAY_1, + }, { + .id = "WT1520", + .hw_id = HWID_NEXX_WT1520, + .layout_id = "4M", + .key = KEY_NEXX_1, + }, { + .id = "WT1520", + .hw_id = HWID_NEXX_WT1520, + .layout_id = "8M", + .key = KEY_NEXX_1, + }, { + .id = "WT3020", + .hw_id = HWID_NEXX_WT3020, + .layout_id = "4M", + .key = KEY_NEXX_2, + }, { + .id = "WT3020", + .hw_id = HWID_NEXX_WT3020, + .layout_id = "8M", + .key = KEY_NEXX_2, + }, { + + + + + /* terminating entry */ + } +}; + +/* + * Message macros + */ +#define ERR(fmt, ...) do { \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt "\n", \ + progname, ## __VA_ARGS__ ); \ +} while (0) + +#define ERRS(fmt, ...) do { \ + int save = errno; \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt ":%s\n", \ + progname, ## __VA_ARGS__, strerror(save)); \ +} while (0) + +#define DBG(fmt, ...) do { \ + fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ +} while (0) + +/* + * Find a board by its name + */ +static struct board_info *find_board(char *id) +{ + struct board_info *ret; + struct board_info *board; + + ret = NULL; + for (board = boards; board->id != NULL; board++){ + if (strcasecmp(id, board->id) == 0) { + ret = board; + break; + } + }; + + return ret; +} + +/* + * Find a board by its hardware ID + */ +static struct board_info *find_board_by_hwid(uint32_t hw_id) +{ + struct board_info *board; + + for (board = boards; board->id != NULL; board++) { + if (hw_id == board->hw_id) + return board; + }; + + return NULL; +} + +/* + * Find a Flash memory layout by its name + */ +static struct flash_layout *find_layout(char *id) +{ + struct flash_layout *ret; + struct flash_layout *l; + + ret = NULL; + for (l = layouts; l->id != NULL; l++){ + if (strcasecmp(id, l->id) == 0) { + ret = l; + break; + } + }; + + return ret; +} + +/* + * Display usage + */ +static void usage(int status) +{ + FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; + + fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stream, +"\n" +"Options:\n" +" -B <board> create image for the board specified with <board>\n" +" -H <hwid> use hardware id specified with <hwid>\n" +" -F <id> use flash layout specified with <id>\n" +" -f <file> read firmware image from the file <file>\n" +" -o <file> write output to the file <file>\n" +" -i inspect given firmware file (requires -f)\n" +" -x extract combined kernel and rootfs while inspecting (implies -i)\n" +" -h show this screen\n" + ); + + exit(status); +} + +/* + * Get file statistics + */ +static int get_file_stat(struct file_info *fdata) +{ + struct stat st; + int res; + + if (fdata->file_name == NULL) { + return 0; + } + res = stat(fdata->file_name, &st); + if (res){ + ERRS("stat failed on %s", fdata->file_name); + return res; + } + + fdata->file_size = st.st_size; + return 0; +} + +/* + * Read file into buffer + */ +static int read_to_buf(struct file_info *fdata, uint8_t *buf) +{ + FILE *f; + int ret = EXIT_FAILURE; + + f = fopen(fdata->file_name, "rb"); + if (f == NULL) { + ERRS("could not open \"%s\" for reading", fdata->file_name); + goto out; + } + + errno = 0; + fread(buf, fdata->file_size, 1, f); + if (errno != 0) { + ERRS("unable to read from file \"%s\"", fdata->file_name); + goto out_close; + } + + ret = EXIT_SUCCESS; + + out_close: + fclose(f); + out: + return ret; +} + +/* + * Check command line options + */ +static int check_options(void) +{ + int ret; + + if (firmware_info.file_name == NULL) { + ERR("no firmware image specified"); + return -1; + } + + ret = get_file_stat(&firmware_info); + if (ret) + return ret; + + if (inspect) + return 0; + + if (board_id == NULL && opt_hw_id == NULL) { + ERR("either board or hardware id must be specified"); + return -1; + } + + if (board_id) { + board = find_board(board_id); + if (board == NULL) { + ERR("unknown/unsupported board id \"%s\"", board_id); + return -1; + } + if (layout_id == NULL) { + layout_id = board->layout_id; + } + hw_id = board->hw_id; + } else { + hw_id = strtoul(opt_hw_id, NULL, 0); + board = find_board_by_hwid(hw_id); + if (layout_id == NULL) { + layout_id = board->layout_id; + } + } + + layout = find_layout(layout_id); + if (layout == NULL) { + ERR("unknown flash layout \"%s\"", layout_id); + return -1; + } + + firmware_len = firmware_info.file_size; + + if (firmware_info.file_size > + layout->fw_max_len - sizeof (struct fw_header)) { + ERR("firmware image is too big"); + return -1; + } + + if (ofname == NULL) { + ERR("no output file specified"); + return -1; + } + return 0; +} + +/* + * Fill in firmware header + */ +static void fill_header(uint8_t *buf) +{ + struct fw_header *hdr = (struct fw_header *) buf; + + memset(hdr, 0, sizeof (struct fw_header)); + hdr->hw_id = HOST_TO_LE32(hw_id); + hdr->firmware_len = HOST_TO_LE32(firmware_len); + hdr->flags = HOST_TO_LE32(HEADER_FLAGS); +} + +/* + * Compute firmware checksum + */ +static uint16_t checksum_fw(uint8_t *data, int len) +{ + int i; + int32_t checksum = 0; + + for (i = 0; i < len - 1; i += 2) { + checksum += (data[i + 1] << 8) | data[i]; + } + if (i < len) { + checksum += data[i]; + } + checksum = checksum + (checksum >> 16) + 0xffff; + checksum = ~(checksum + (checksum >> 16)) & 0xffff; + return (uint16_t) checksum; +} + +/* + * (De)obfuscate firmware using an XOR operation with a fixed length key + */ +static void xor_fw(uint8_t *data, int len) +{ + int i; + + for (i = 0; i <= len; i++) { + data[i] ^= key[board->key][i % KEY_LEN]; + } +} + +/* + * Write firmware to file + */ +static int write_fw(uint8_t *data, int len) +{ + FILE *f; + int ret = EXIT_FAILURE; + + f = fopen(ofname, "wb"); + if (f == NULL) { + ERRS("could not open \"%s\" for writing", ofname); + goto out; + } + + errno = 0; + fwrite(data, len, 1, f); + if (errno) { + ERRS("unable to write output file"); + goto out_flush; + } + + DBG("firmware file \"%s\" completed", ofname); + + ret = EXIT_SUCCESS; + + out_flush: + fflush(f); + fclose(f); + if (ret != EXIT_SUCCESS) { + unlink(ofname); + } + out: + return ret; +} + +/* + * Build firmware file + */ +static int build_fw(void) +{ + int buflen; + uint8_t *buf, *p; + int ret = EXIT_FAILURE; + int writelen = 0; + uint16_t checksum; + + buflen = layout->fw_max_len; + + buf = (uint8_t *) malloc(buflen); + if (!buf) { + ERR("no memory for buffer\n"); + goto out; + } + + memset(buf, 0xff, buflen); + p = buf + sizeof (struct fw_header); + ret = read_to_buf(&firmware_info, p); + if (ret) { + goto out_free_buf; + } + writelen = sizeof (struct fw_header) + firmware_len + 2; + + /* Fill in header */ + fill_header(buf); + + /* Compute firmware checksum */ + checksum = checksum_fw(buf + sizeof (struct fw_header), firmware_len); + + /* Cannot use network order function because checksum is not word-aligned */ + buf[writelen - 1] = checksum >> 8; + buf[writelen - 2] = checksum & 0xff; + + /* XOR obfuscate firmware */ + xor_fw(buf + sizeof (struct fw_header), firmware_len + 2); + + /* Write firmware file */ + ret = write_fw(buf, writelen); + if (ret) { + goto out_free_buf; + } + ret = EXIT_SUCCESS; + + out_free_buf: + free(buf); + out: + return ret; +} + +/* Helper functions to inspect_fw() representing different output formats */ +static inline void inspect_fw_pstr(char *label, char *str) +{ + printf("%-23s: %s\n", label, str); +} + +static inline void inspect_fw_phex(char *label, uint32_t val) +{ + printf("%-23s: 0x%08x\n", label, val); +} + +static inline void inspect_fw_phexpost(char *label, + uint32_t val, char *post) +{ + printf("%-23s: 0x%08x (%s)\n", label, val, post); +} + +static inline void inspect_fw_phexdef(char *label, + uint32_t val, uint32_t defval) +{ + printf("%-23s: 0x%08x ", label, val); + + if (val == defval) { + printf("(== OpenWrt default)\n"); + } else { + printf("(OpenWrt default: 0x%08x)\n", defval); + } +} + +static inline void inspect_fw_phexexp(char *label, + uint32_t val, uint32_t expval) +{ + printf("%-23s: 0x%08x ", label, val); + + if (val == expval) { + printf("(ok)\n"); + } else { + printf("(expected: 0x%08x)\n", expval); + } +} + +static inline void inspect_fw_phexdec(char *label, uint32_t val) +{ + printf("%-23s: 0x%08x / %8u bytes\n", label, val, val); +} + +static inline void inspect_fw_pchecksum(char *label, + uint16_t val, uint16_t expval) +{ + printf("%-23s: 0x%04x ", label, val); + if (val == expval) { + printf("(ok)\n"); + } else { + printf("(expected: 0x%04x)\n", expval); + } +} + +static int inspect_fw(void) +{ + uint8_t *buf; + struct fw_header *hdr; + int ret = EXIT_FAILURE; + uint16_t computed_checksum, file_checksum; + + buf = (uint8_t *) malloc(firmware_info.file_size); + if (!buf) { + ERR("no memory for buffer!\n"); + goto out; + } + + ret = read_to_buf(&firmware_info, buf); + if (ret) { + goto out_free_buf; + } + hdr = (struct fw_header *)buf; + + inspect_fw_pstr("File name", firmware_info.file_name); + inspect_fw_phexdec("File size", firmware_info.file_size); + + printf("\n"); + + inspect_fw_phexdec("Header size", sizeof (struct fw_header)); + board = find_board_by_hwid(LE32_TO_HOST(hdr->hw_id)); + if (board) { + layout = find_layout(board->layout_id); + inspect_fw_phexpost("Hardware ID", + LE32_TO_HOST( hdr->hw_id), board->id); + } else { + inspect_fw_phexpost("Hardware ID", + LE32_TO_HOST(hdr->hw_id), "unknown"); + } + inspect_fw_phexdec("Firmware data length", + LE32_TO_HOST(hdr->firmware_len)); + + inspect_fw_phexexp("Flags", + LE32_TO_HOST(hdr->flags), HEADER_FLAGS); + printf("\n"); + + /* XOR unobfuscate firmware */ + xor_fw(buf + sizeof (struct fw_header), LE32_TO_HOST(hdr->firmware_len) + 2); + + /* Compute firmware checksum */ + computed_checksum = checksum_fw(buf + sizeof (struct fw_header), LE32_TO_HOST(hdr->firmware_len)); + + /* Cannot use network order function because checksum is not word-aligned */ + file_checksum = (buf[firmware_info.file_size - 1] << 8) | buf[firmware_info.file_size - 2]; + inspect_fw_pchecksum("Firmware checksum", computed_checksum, file_checksum); + + /* Verify checksum */ + if (computed_checksum != file_checksum) { + ret = -1; + ERR("checksums do not match"); + goto out_free_buf; + } + + printf("\n"); + + if (extract) { + FILE *fp; + char *filename; + + if (ofname == NULL) { + filename = malloc(strlen(firmware_info.file_name) + 10); + sprintf(filename, "%s-firmware", firmware_info.file_name); + } else { + filename = ofname; + } + printf("Extracting firmware to \"%s\"...\n", filename); + fp = fopen(filename, "wb"); + if (fp) { + if (!fwrite(buf + sizeof (struct fw_header), + LE32_TO_HOST(hdr->firmware_len), 1, fp)) { + ERRS("error in fwrite(): %s", strerror(errno)); + } + fclose(fp); + } else { + ERRS("error in fopen(): %s", strerror(errno)); + } + if (ofname == NULL) { + free(filename); + } + printf("\n"); + } + + out_free_buf: + free(buf); + out: + return ret; +} + +/* + * Main entry point + */ +int main(int argc, char *argv[]) +{ + int ret = EXIT_FAILURE; + + progname = basename(argv[0]); + + int c; + + while ((c = getopt(argc, argv, "B:H:F:f:o:ixh")) != -1) { + switch (c) { + case 'B': + board_id = optarg; + break; + case 'H': + opt_hw_id = optarg; + break; + case 'F': + layout_id = optarg; + break; + case 'f': + firmware_info.file_name = optarg; + break; + case 'o': + ofname = optarg; + break; + case 'i': + inspect = 1; + break; + case 'x': + inspect = 1; + extract = 1; + break; + case 'h': + usage(EXIT_SUCCESS); + break; + default: + usage(EXIT_FAILURE); + break; + } + } + + ret = check_options(); + if (ret) { + goto out; + } + if (!inspect) { + ret = build_fw(); + } else { + ret = inspect_fw(); + } + + out: + return ret; +} diff --git a/tools/firmware-utils/src/mkrtn56uimg.c b/tools/firmware-utils/src/mkrtn56uimg.c new file mode 100644 index 00000000000..92aaf314a17 --- /dev/null +++ b/tools/firmware-utils/src/mkrtn56uimg.c @@ -0,0 +1,293 @@ +/* + * + * Copyright (C) 2014 OpenWrt.org + * Copyright (C) 2014 Mikko Hissa <mikko.hissa@werzek.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netinet/in.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <unistd.h> +#include <zlib.h> + +#define IH_MAGIC 0x27051956 +#define IH_NMLEN 32 +#define IH_PRODLEN 23 + +#define IH_TYPE_INVALID 0 +#define IH_TYPE_STANDALONE 1 +#define IH_TYPE_KERNEL 2 +#define IH_TYPE_RAMDISK 3 +#define IH_TYPE_MULTI 4 +#define IH_TYPE_FIRMWARE 5 +#define IH_TYPE_SCRIPT 6 +#define IH_TYPE_FILESYSTEM 7 + +/* + * Compression Types + */ +#define IH_COMP_NONE 0 +#define IH_COMP_GZIP 1 +#define IH_COMP_BZIP2 2 +#define IH_COMP_LZMA 3 + +typedef struct { + uint8_t major; + uint8_t minor; +} version_t; + +typedef struct { + version_t kernel; + version_t fs; + uint8_t productid[IH_PRODLEN]; + uint8_t sub_fs; + uint32_t ih_ksz; +} asus_t; + +typedef struct image_header { + uint32_t ih_magic; + uint32_t ih_hcrc; + uint32_t ih_time; + uint32_t ih_size; + uint32_t ih_load; + uint32_t ih_ep; + uint32_t ih_dcrc; + uint8_t ih_os; + uint8_t ih_arch; + uint8_t ih_type; + uint8_t ih_comp; + union { + uint8_t ih_name[IH_NMLEN]; + asus_t asus; + } tail; +} image_header_t; + +typedef struct squashfs_sb { + uint32_t s_magic; + uint32_t pad0[9]; + uint64_t bytes_used; +} squashfs_sb_t; + +typedef enum { + NONE, FACTORY, SYSUPGRADE, +} op_mode_t; + +void +calc_crc(image_header_t *hdr, void *data, uint32_t len) +{ + /* + * Calculate payload checksum + */ + hdr->ih_dcrc = htonl(crc32(0, (Bytef *)data, len)); + hdr->ih_size = htonl(len); + /* + * Calculate header checksum + */ + hdr->ih_hcrc = 0; + hdr->ih_hcrc = htonl(crc32(0, (Bytef *)hdr, sizeof(image_header_t))); +} + + +static void +usage(const char *progname, int status) +{ + FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; + int i; + + fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stream, "\n" + "Options:\n" + " -f <file> generate a factory flash image <file>\n" + " -s <file> generate a sysupgrade flash image <file>\n" + " -h show this screen\n"); + exit(status); +} + +int +process_image(char *progname, char *filename, op_mode_t opmode) +{ + int fd, len; + void *data, *ptr; + char namebuf[IH_NMLEN]; + struct stat sbuf; + uint32_t checksum, offset_kernel, offset_sqfs, offset_end, + offset_sec_header, offset_eb, offset_image_end; + squashfs_sb_t *sqs; + image_header_t *hdr; + + if ((fd = open(filename, O_RDWR, 0666)) < 0) { + fprintf (stderr, "%s: Can't open %s: %s\n", + progname, filename, strerror(errno)); + return (EXIT_FAILURE); + } + + if (fstat(fd, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + progname, filename, strerror(errno)); + return (EXIT_FAILURE); + } + + if ((unsigned)sbuf.st_size < sizeof(image_header_t)) { + fprintf (stderr, + "%s: Bad size: \"%s\" is no valid image\n", + progname, filename); + return (EXIT_FAILURE); + } + + ptr = (void *)mmap(0, sbuf.st_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + fd, 0); + + if ((caddr_t)ptr == (caddr_t)-1) { + fprintf (stderr, "%s: Can't read %s: %s\n", + progname, filename, strerror(errno)); + return (EXIT_FAILURE); + } + + hdr = ptr; + + if (ntohl(hdr->ih_magic) != IH_MAGIC) { + fprintf (stderr, + "%s: Bad Magic Number: \"%s\" is no valid image\n", + progname, filename); + return (EXIT_FAILURE); + } + + if (opmode == FACTORY) { + strncpy(namebuf, hdr->tail.ih_name, IH_NMLEN); + hdr->tail.asus.kernel.major = 0; + hdr->tail.asus.kernel.minor = 0; + hdr->tail.asus.fs.major = 0; + hdr->tail.asus.fs.minor = 0; + strncpy((char *)&hdr->tail.asus.productid, "RT-N56U", IH_PRODLEN); + } + + if (hdr->tail.asus.ih_ksz == 0) + hdr->tail.asus.ih_ksz = htonl(ntohl(hdr->ih_size) + sizeof(image_header_t)); + + offset_kernel = sizeof(image_header_t); + offset_sqfs = ntohl(hdr->tail.asus.ih_ksz); + sqs = ptr + offset_sqfs; + offset_sec_header = offset_sqfs + sqs->bytes_used; + + /* + * Reserve space for the second header. + */ + offset_end = offset_sec_header + sizeof(image_header_t); + offset_eb = ((offset_end>>16)+1)<<16; + + if (opmode == FACTORY) + offset_image_end = offset_eb + 4; + else + offset_image_end = sbuf.st_size; + /* + * Move the second header at the end of the image. + */ + offset_end = offset_sec_header; + offset_sec_header = offset_eb - sizeof(image_header_t); + + /* + * Remove jffs2 markers between squashfs and eb boundary. + */ + if (opmode == FACTORY) + memset(ptr+offset_end, 0xff ,offset_eb - offset_end); + + /* + * Grow the image if needed. + */ + if (offset_image_end > sbuf.st_size) { + (void) munmap((void *)ptr, sbuf.st_size); + ftruncate(fd, offset_image_end); + ptr = (void *)mmap(0, offset_image_end, + PROT_READ | PROT_WRITE, + MAP_SHARED, + fd, 0); + /* + * jffs2 marker + */ + if (opmode == FACTORY) { + *(uint8_t *)(ptr+offset_image_end-4) = 0xde; + *(uint8_t *)(ptr+offset_image_end-3) = 0xad; + *(uint8_t *)(ptr+offset_image_end-2) = 0xc0; + *(uint8_t *)(ptr+offset_image_end-1) = 0xde; + } + } + + /* + * Calculate checksums for the second header to be used after flashing. + */ + if (opmode == FACTORY) { + hdr = ptr+offset_sec_header; + memcpy(hdr, ptr, sizeof(image_header_t)); + strncpy(hdr->tail.ih_name, namebuf, IH_NMLEN); + calc_crc(hdr, ptr+offset_kernel, offset_sqfs - offset_kernel); + calc_crc((image_header_t *)ptr, ptr+offset_kernel, offset_image_end - offset_kernel); + } else { + calc_crc((image_header_t *)ptr, ptr+offset_kernel, offset_sqfs - offset_kernel); + } + + if (sbuf.st_size > offset_image_end) + (void) munmap((void *)ptr, sbuf.st_size); + else + (void) munmap((void *)ptr, offset_image_end); + + ftruncate(fd, offset_image_end); + (void) close (fd); + + return EXIT_SUCCESS; +} + +int +main(int argc, char **argv) +{ + int opt; + char *filename, *progname; + op_mode_t opmode = NONE; + + progname = argv[0]; + + while ((opt = getopt(argc, argv,":s:f:h?")) != -1) { + switch (opt) { + case 's': + opmode = SYSUPGRADE; + filename = optarg; + break; + case 'f': + opmode = FACTORY; + filename = optarg; + break; + case 'h': + opmode = NONE; + default: + usage(progname, EXIT_FAILURE); + opmode = NONE; + } + } + + if(filename == NULL) + opmode = NONE; + + switch (opmode) { + case NONE: + usage(progname, EXIT_FAILURE); + break; + case FACTORY: + case SYSUPGRADE: + return process_image(progname, filename, opmode); + break; + } + + return EXIT_SUCCESS; +} + diff --git a/tools/firmware-utils/src/mksenaofw.c b/tools/firmware-utils/src/mksenaofw.c new file mode 100644 index 00000000000..0f10ebdfbeb --- /dev/null +++ b/tools/firmware-utils/src/mksenaofw.c @@ -0,0 +1,420 @@ +/* + * + * Copyright (C) 2012 OpenWrt.org + * Copyright (C) 2012 Mikko Hissa <mikko.hissa@uta.fi> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <libgen.h> +#include <errno.h> +#include <arpa/inet.h> +#include <unistd.h> +#include "md5.h" + +#define HDR_LEN 0x60 +#define BUF_SIZE 0x200 +#define VERSION_SIZE 0x10 +#define MD5_SIZE 0x10 +#define PAD_SIZE 0x20 + +#define DEFAULT_BLOCK_SIZE 65535 + +#define DEFAULT_HEAD_VALUE 0x0 +#define DEFAULT_VERSION "123" +#define DEFAULT_MAGIC 0x12345678 + +typedef struct { + uint32_t head; + uint32_t vendor_id; + uint32_t product_id; + uint8_t version[VERSION_SIZE]; + uint32_t firmware_type; + uint32_t filesize; + uint32_t zero; + uint8_t md5sum[MD5_SIZE]; + uint8_t pad[PAD_SIZE]; + uint32_t chksum; + uint32_t magic; +} img_header; + +typedef struct { + uint8_t id; + char * name; +} firmware_type; + +typedef enum { + NONE, ENCODE, DECODE +} op_mode; + +static firmware_type FIRMWARE_TYPES[] = { + { 0x01, "bootloader" }, + { 0x02, "kernel" }, + { 0x03, "kernelapp" }, + { 0x04, "apps" }, + /* The types below this line vary by manufacturer */ + { 0x05, "littleapps (D-Link)/factoryapps (EnGenius)" }, + { 0x06, "sounds (D-Link)/littleapps (EnGenius)" }, + { 0x07, "userconfig (D-Link)/appdata (EnGenius)" }, + { 0x08, "userconfig (EnGenius)"}, + { 0x09, "odmapps (EnGenius)"}, + { 0x0a, "factoryapps (D-Link)" }, + { 0x0b, "odmapps (D-Link)" }, + { 0x0c, "langpack (D-Link)" } +}; + +static long get_file_size(const char *filename) +{ + FILE *fp_file; + long result; + + fp_file = fopen(filename, "r"); + if (!fp_file) + return -1; + fseek(fp_file, 0, SEEK_END); + result = ftell(fp_file); + fclose(fp_file); + return result; +} + +static int header_checksum(void *data, int len) +{ + int i; + int sum; + + sum = 0; + if (data != NULL && len >= 0) { + for (i = 0; i < len; ++i) + sum += *(unsigned char *) (data + i); + return sum; + } + + return -1; +} + +static int md5_file(const char *filename, uint8_t *dst) +{ + FILE *fp_src; + MD5_CTX ctx; + char buf[BUF_SIZE]; + size_t bytes_read; + + MD5_Init(&ctx); + + fp_src = fopen(filename, "r+b"); + if (!fp_src) { + return -1; + } + while (!feof(fp_src)) { + bytes_read = fread(&buf, 1, BUF_SIZE, fp_src); + MD5_Update(&ctx, &buf, bytes_read); + } + fclose(fp_src); + + MD5_Final(dst, &ctx); + + return 0; +} + +static int encode_image(const char *input_file_name, + const char *output_file_name, img_header *header, int block_size) +{ + char buf[BUF_SIZE]; + size_t bytes_read; + size_t pad_len = 0; + size_t bytes_avail; + + FILE *fp_input; + FILE *fp_output; + + int i; + long magic; + + fp_input = fopen(input_file_name, "r+b"); + if (!fp_input) { + fprintf(stderr, "Cannot open %s !!\n", input_file_name); + return -1; + } + + fp_output = fopen(output_file_name, "w+b"); + if (!fp_output) { + fprintf(stderr, "Cannot open %s !!\n", output_file_name); + fclose(fp_input); + return -1; + } + + header->filesize = get_file_size(input_file_name); + if (!header->filesize) { + fprintf(stderr, "File %s open/size error!\n", input_file_name); + fclose(fp_input); + fclose(fp_output); + return -1; + } + /* + * Zero padding + */ + if (block_size > 0) { + pad_len = block_size - (header->filesize % block_size); + } + + if (md5_file(input_file_name, (uint8_t *) &header->md5sum) < 0) { + fprintf(stderr, "MD5 failed on file %s\n", input_file_name); + fclose(fp_input); + fclose(fp_output); + return -1; + } + header->zero = 0; + header->chksum = header_checksum(header, HDR_LEN); + header->head = htonl(header->head); + header->vendor_id = htonl(header->vendor_id); + header->product_id = htonl(header->product_id); + header->firmware_type = htonl(header->firmware_type); + header->filesize = htonl(header->filesize); + header->chksum = htonl(header->chksum); + magic = header->magic; + header->magic = htonl(header->magic); + + fwrite(header, HDR_LEN, 1, fp_output); + + while (!feof(fp_input) || pad_len > 0) { + + if (!feof(fp_input)) + bytes_read = fread(&buf, 1, BUF_SIZE, fp_input); + else + bytes_read = 0; + + /* + * No more bytes read, start padding + */ + if (bytes_read < BUF_SIZE && pad_len > 0) { + bytes_avail = BUF_SIZE - bytes_read; + memset( &buf[bytes_read], 0, bytes_avail); + bytes_read += bytes_avail < pad_len ? bytes_avail : pad_len; + pad_len -= bytes_avail < pad_len ? bytes_avail : pad_len; + } + + for (i = 0; i < bytes_read; i++) + buf[i] ^= magic >> (i % 8) & 0xff; + fwrite(&buf, bytes_read, 1, fp_output); + } + + fclose(fp_input); + fclose(fp_output); + return 1; +} + +int decode_image(const char *input_file_name, const char *output_file_name) +{ + img_header header; + char buf[BUF_SIZE]; + + FILE *fp_input; + FILE *fp_output; + unsigned int i; + + size_t bytes_read; + size_t bytes_written; + + fp_input = fopen(input_file_name, "r+b"); + if (!fp_input) { + fprintf(stderr, "Cannot open %s !!\n", input_file_name); + fclose(fp_input); + return -1; + } + + fp_output = fopen(output_file_name, "w+b"); + if (!fp_output) { + fprintf(stderr, "Cannot open %s !!\n", output_file_name); + fclose(fp_output); + return -1; + } + + if (fread(&header, 1, HDR_LEN, fp_input) != HDR_LEN) { + fprintf(stderr, "Incorrect header size!!"); + fclose(fp_input); + fclose(fp_output); + return -1; + } + + header.head = ntohl(header.head); + header.vendor_id = ntohl(header.vendor_id); + header.product_id = ntohl(header.product_id); + header.firmware_type = ntohl(header.firmware_type); + header.filesize = ntohl(header.filesize); + header.chksum = ntohl(header.chksum); + header.magic = ntohl(header.magic); + + bytes_written = 0; + while (!feof(fp_input)) { + + bytes_read = fread(&buf, 1, BUF_SIZE, fp_input); + for (i = 0; i < bytes_read; i++) + buf[i] ^= header.magic >> (i % 8) & 0xff; + + /* + * Handle padded source file + */ + if (bytes_written + bytes_read > header.filesize) { + bytes_read = header.filesize - bytes_written; + if (bytes_read > 0) + fwrite(&buf, bytes_read, 1, fp_output); + break; + } + + fwrite(&buf, bytes_read, 1, fp_output); + bytes_written += bytes_read; + } + + fclose(fp_input); + fclose(fp_output); + + return 1; +} + +static void usage(const char *progname, int status) +{ + FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; + int i; + + fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stream, "\n" + "Options:\n" + " -e <file> encode image file <file>\n" + " -d <file> decode image file <file>\n" + " -o <file> write output to the file <file>\n" + " -t <type> set image type to <type>\n" + " valid image <type> values:\n"); + for (i = 0; i < sizeof(FIRMWARE_TYPES) / sizeof(firmware_type); i++) { + fprintf(stream, " %-5i= %s\n", FIRMWARE_TYPES[i].id, + FIRMWARE_TYPES[i].name); + } + fprintf(stream, " -v <version> set image version to <version>\n" + " -r <vendor> set image vendor id to <vendor>\n" + " -p <product> set image product id to <product>\n" + " -m <magic> set encoding magic <magic>\n" + " -z enable image padding to <blocksize>\n" + " -b <blocksize> set image <blocksize>, defaults to %u\n" + " -h show this screen\n", DEFAULT_BLOCK_SIZE); + exit(status); +} + +int main(int argc, char *argv[]) +{ + int opt; + char *input_file, *output_file, *progname = NULL; + op_mode mode = NONE; + int tmp, i, pad = 0; + int block_size; + img_header header; + + block_size = DEFAULT_BLOCK_SIZE; + progname = basename(argv[0]); + + memset(&header, 0, sizeof( img_header )); + header.magic = DEFAULT_MAGIC; + header.head = DEFAULT_HEAD_VALUE; + strncpy( (char*)&header.version, DEFAULT_VERSION, VERSION_SIZE - 1); + + while ((opt = getopt(argc, argv, ":o:e:d:t:v:r:p:m:b:h?z")) != -1) { + switch (opt) { + case 'e': + input_file = optarg; + mode = ENCODE; + break; + case 'd': + input_file = optarg; + mode = DECODE; + break; + case 'o': + output_file = optarg; + break; + case 't': + tmp = strtol(optarg, 0, 10); + for (i = 0; i < sizeof(FIRMWARE_TYPES) / sizeof(firmware_type); + i++) { + if (FIRMWARE_TYPES[i].id == tmp) { + header.firmware_type = FIRMWARE_TYPES[i].id; + break; + } + } + if (header.firmware_type == 0) { + fprintf(stderr, "Invalid firmware type \"0\"!\n"); + usage(progname, EXIT_FAILURE); + } + break; + case 'v': + strncpy( (char*)&header.version, optarg, + VERSION_SIZE - 1); + break; + case 'r': + header.vendor_id = strtol(optarg, 0, 0); + break; + case 'p': + header.product_id = strtol(optarg, 0, 0); + break; + case 'm': + header.magic = strtoul(optarg, 0, 16); + break; + case 'z': + pad = 1; + break; + case 'b': + block_size = strtol(optarg, 0, 10); + break; + case 'h': + usage(progname, EXIT_SUCCESS); + break; + case ':': + fprintf(stderr, "Option -%c requires an operand\n", optopt); + usage(progname, EXIT_FAILURE); + break; + case '?': + fprintf(stderr, "Unrecognized option: -%c\n", optopt); + usage(progname, EXIT_FAILURE); + break; + default: + usage(progname, EXIT_FAILURE); + break; + } + } + + /* Check required arguments */ + if (mode == NONE) { + fprintf(stderr, "A mode must be defined\n"); + usage(progname, EXIT_FAILURE); + } + + if (input_file == NULL || output_file == NULL) { + fprintf(stderr, "Input and output files must be defined\n"); + usage(progname, EXIT_FAILURE); + } + + if (mode == DECODE) { + if (decode_image(input_file, output_file) < 0) + return EXIT_FAILURE; + + return EXIT_SUCCESS; + } + + if (header.firmware_type == 0) { + fprintf(stderr, "Firmware type must be defined\n"); + usage(progname, EXIT_FAILURE); + } + + if (header.vendor_id == 0 || header.product_id == 0) { + fprintf(stderr, "Vendor ID and Product ID must be defined and non-zero\n"); + usage(progname, EXIT_FAILURE); + } + + if (encode_image(input_file, output_file, &header, pad ? block_size : 0) < 0) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} diff --git a/tools/firmware-utils/src/mksercommfw.c b/tools/firmware-utils/src/mksercommfw.c new file mode 100644 index 00000000000..7f31d4f4c79 --- /dev/null +++ b/tools/firmware-utils/src/mksercommfw.c @@ -0,0 +1,255 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/types.h> + +/* #define DEBUG 1 */ + +/* + * Fw Header Layout for Netgear / Sercomm devices + * */ +static const char *magic = "sErCoMm"; /* 7 */ +/* 7-11: version control/download control ? */ +unsigned char version[4] = {0x00, 0x01, 0x00, 0x00}; +char *hwID = ""; /* 11-43 , ASCII/HEX */ +char *hwVer = ""; /* 44-57 , ASCII/HEX */ +char *swVer = ""; /* 58-62 , ASCII/HEX */ +/* magic again. */ + +#define HEADER_SIZE 71 + +/* null bytes until 511 */ +u_int32_t checksum = 0xFF; /* checksum */ +/* 512 onwards -> ZIP containing rootfs with the same Header */ + + +/* appended on rootfs for the Header. */ +const int footer_size = 128; + +struct file_info { + char *file_name; /* name of the file */ + char *file_data; /* data of the file in memory */ + u_int32_t file_size; /* length of the file */ +}; + +u_int8_t getCheckSum(char *data, int len) +{ + + int32_t previous = 0; + u_int32_t new = 0; + + for (u_int32_t i = 0; i < len; i++) { + new = (data[i] + previous) % 256; + previous = new | previous & -256; + } + return (u_int8_t) new; +} + +void *bufferFile(struct file_info *finfo, int dontload) +{ + int fs = 0; + FILE *f = NULL; + +#ifdef DEBUG + printf("Opening file: %s\n", finfo->file_name); +#endif + f = fopen(finfo->file_name, "rb"); + if (f == NULL) { + perror("Error"); + exit(1); + } + + fseek(f, 0L, SEEK_END); + fs = ftell(f); + rewind(f); + +#ifdef DEBUG + printf("Filesize: %i .\n", fs); +#endif + + finfo->file_size = fs; + + if (dontload) { + return 0; + } + + char *data = malloc(fs); + finfo->file_data = data; + + int read = fread(data, fs, 1, f); + + if (read != 1) { + printf("Error reading file %s.", finfo->file_name); + exit(1); + } + +#ifdef DEBUG + printf("File: read successfully %i bytes.\n", read*fs); +#endif + fclose(f); +} + +void *writeFile(struct file_info *finfo) +{ + +#ifdef DEBUG + printf("Writing file: %s.\n", finfo->file_name); +#endif + + FILE *fout = fopen(finfo->file_name, "w"); + + if (!fwrite(finfo->file_data, finfo->file_size, 1, fout)) { + printf("Wanted to write, but something went wrong.\n"); + fclose(fout); + exit(1); + } + fclose(fout); +} + +void *rmFile(struct file_info *finfo) +{ + remove(finfo->file_name); + free(finfo->file_data); + finfo->file_size = 0; +} + +void *usage(char *argv[]) +{ + printf("Usage: %s <sysupgradefile> <kernel_offset> <HWID> <HWVER> <SWID>\n" + "All are positional arguments ... \n" + " sysupgradefile: File with the kernel uimage at 0\n" + " kernel_offset: Offset in Hex where the kernel is located\n" + " HWID: Hardware ID, ASCII\n" + " HWVER: Hardware Version, ASCII\n" + " SWID: Software Version, Hex\n" + " \n" + " ", argv[0]); +} + +int main(int argc, char *argv[]) +{ + printf("Building fw image for sercomm devices.\n"); + + if (argc == 2) { + struct file_info myfile = {argv[1], 0, 0}; + bufferFile(&myfile, 0); + char chksum = getCheckSum(myfile.file_data, myfile.file_size); + printf("Checksum for File: %X.\n", chksum); + return 0; + } + + if (argc != 6) { + usage(argv); + return 1; + } + + /* Args */ + + struct file_info sysupgrade = {argv[1], 0, 0}; + bufferFile(&sysupgrade, 0); + + int kernel_offset = 0x90000; /* offset for the kernel inside the rootfs, default val */ + sscanf(argv[2], "%X", &kernel_offset); +#ifdef DEBUG + printf("Kernel_offset: at %X/%i bytes.\n", kernel_offset, kernel_offset); +#endif + char *hwID = argv[3]; + char *hwVer = argv[4]; + u_int32_t swVer = 0; + sscanf(argv[5],"%4X",&swVer); + swVer = bswap_32(swVer); + + char *rootfsname = malloc(2*strlen(sysupgrade.file_name) + 8); + sprintf(rootfsname, "%s.rootfs", sysupgrade.file_name); + + char *zipfsname = malloc(2*strlen(rootfsname) + 5); + sprintf(zipfsname, "%s.zip", rootfsname); + /* / Args */ + +#ifdef DEBUG + printf("Building header: %s %s %2X %s.\n", hwID , hwVer, swVer, magic); +#endif + /* Construct the firmware header/magic */ + struct file_info header = {0, 0, 0}; + header.file_size = HEADER_SIZE; + header.file_data = malloc(HEADER_SIZE); + bzero(header.file_data, header.file_size); + + char *tg = header.file_data; + strcpy(tg, magic); + memcpy(tg+7, version, 4*sizeof(char)); + strcpy(tg+11, hwID); + strcpy(tg+45, hwVer); + memcpy(tg+55, &swVer,sizeof(u_int32_t)); + strcpy(tg+63, magic); + +#ifdef DEBUG + printf("Header done, now creating rootfs."); +#endif + /* Construct a rootfs */ + struct file_info rootfs = {0, 0, 0}; + rootfs.file_size = sysupgrade.file_size + kernel_offset + footer_size; + rootfs.file_data = malloc(rootfs.file_size); + bzero(rootfs.file_data, rootfs.file_size); + rootfs.file_name = rootfsname; + + /* copy Owrt image to Kernel location */ + memcpy(rootfs.file_data+kernel_offset, sysupgrade.file_data, sysupgrade.file_size); + + /* 22 added to get away from sysup image, no other reason. + * updater searches for magic anyway */ + tg = rootfs.file_data + kernel_offset + sysupgrade.file_size+22; + + memcpy(tg, header.file_data, header.file_size); + writeFile(&rootfs); + +#ifdef DEBUG + printf("Preparing to zip.\n"); +#endif + /* now that we got the rootfs, repeat the whole thing again(sorta): + * 1. zip the rootfs */ + char *zipper = malloc(5 + 2*strlen(rootfs.file_name) + 4); + sprintf(zipper, "%s %s %s", "zip ", zipfsname, rootfs.file_name); + int ret = system(zipper); + + /* clear rootfs file */ + rmFile(&rootfs); + + /* and load zipped fs */ + struct file_info zippedfs = {zipfsname, 0, 0}; + bufferFile(&zippedfs, 0); + +#ifdef DEBUG + printf("Creating Image.\n"); +#endif + + /* 2. create new file 512+rootfs size */ + struct file_info image = {argv[1], 0, 0}; + image.file_data = malloc(zippedfs.file_size + 512); + image.file_size = zippedfs.file_size + 512; + + /* 3. copy zipfile at loc 512 */ + memcpy(image.file_data+512, zippedfs.file_data, zippedfs.file_size); + rmFile(&zippedfs); + + /* 4. add header to file */ + memcpy(image.file_data, header.file_data, header.file_size); + + /* 5. do a checksum run, and compute checksum */ + char chksum = getCheckSum(image.file_data, image.file_size); +#ifdef DEBUG + printf("Checksum for Image: %X.\n", chksum); +#endif + + /* 6. write the checksum invert into byte 511 to bring it to 0 */ + chksum = (chksum ^ 0xFF) + 1; + memcpy(image.file_data+511, &chksum, 1); + + chksum = getCheckSum(image.file_data, image.file_size); +#ifdef DEBUG + printf("Checksum for after fix: %X.\n", chksum); +#endif + /* 7. pray that the updater will accept the file */ + writeFile(&image); + return 0; +} diff --git a/tools/firmware-utils/src/mktplinkfw-lib.c b/tools/firmware-utils/src/mktplinkfw-lib.c new file mode 100644 index 00000000000..e3213274c19 --- /dev/null +++ b/tools/firmware-utils/src/mktplinkfw-lib.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> + * + * This tool was based on: + * TP-Link WR941 V2 firmware checksum fixing tool. + * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> /* for unlink() */ +#include <libgen.h> +#include <getopt.h> /* for getopt() */ +#include <stdarg.h> +#include <stdbool.h> +#include <endian.h> +#include <errno.h> +#include <sys/stat.h> + +#include <arpa/inet.h> +#include <netinet/in.h> + +#include "mktplinkfw-lib.h" +#include "md5.h" + +extern char *ofname; +extern char *progname; +extern uint32_t kernel_len; +extern struct file_info kernel_info; +extern struct file_info rootfs_info; +extern struct flash_layout *layout; +extern uint32_t rootfs_ofs; +extern uint32_t rootfs_align; +extern int combined; +extern int strip_padding; +extern int add_jffs2_eof; + +static unsigned char jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde}; + +void fill_header(char *buf, int len); + +struct flash_layout *find_layout(struct flash_layout *layouts, const char *id) +{ + struct flash_layout *ret; + struct flash_layout *l; + + ret = NULL; + for (l = layouts; l->id != NULL; l++){ + if (strcasecmp(id, l->id) == 0) { + ret = l; + break; + } + }; + + return ret; +} + +void get_md5(const char *data, int size, uint8_t *md5) +{ + MD5_CTX ctx; + + MD5_Init(&ctx); + MD5_Update(&ctx, data, size); + MD5_Final(md5, &ctx); +} + +int get_file_stat(struct file_info *fdata) +{ + struct stat st; + int res; + + if (fdata->file_name == NULL) + return 0; + + res = stat(fdata->file_name, &st); + if (res){ + ERRS("stat failed on %s", fdata->file_name); + return res; + } + + fdata->file_size = st.st_size; + return 0; +} + +int read_to_buf(const struct file_info *fdata, char *buf) +{ + FILE *f; + int ret = EXIT_FAILURE; + + f = fopen(fdata->file_name, "r"); + if (f == NULL) { + ERRS("could not open \"%s\" for reading", fdata->file_name); + goto out; + } + + errno = 0; + fread(buf, fdata->file_size, 1, f); + if (errno != 0) { + ERRS("unable to read from file \"%s\"", fdata->file_name); + goto out_close; + } + + ret = EXIT_SUCCESS; + +out_close: + fclose(f); +out: + return ret; +} + +static int pad_jffs2(char *buf, int currlen, int maxlen) +{ + int len; + uint32_t pad_mask; + + len = currlen; + pad_mask = (4 * 1024) | (64 * 1024); /* EOF at 4KB and at 64KB */ + while ((len < maxlen) && (pad_mask != 0)) { + uint32_t mask; + int i; + + for (i = 10; i < 32; i++) { + mask = 1 << i; + if (pad_mask & mask) + break; + } + + len = ALIGN(len, mask); + + for (i = 10; i < 32; i++) { + mask = 1 << i; + if ((len & (mask - 1)) == 0) + pad_mask &= ~mask; + } + + for (i = 0; i < sizeof(jffs2_eof_mark); i++) + buf[len + i] = jffs2_eof_mark[i]; + + len += sizeof(jffs2_eof_mark); + } + + return len; +} + +int write_fw(const char *ofname, const char *data, int len) +{ + FILE *f; + int ret = EXIT_FAILURE; + + f = fopen(ofname, "w"); + if (f == NULL) { + ERRS("could not open \"%s\" for writing", ofname); + goto out; + } + + errno = 0; + fwrite(data, len, 1, f); + if (errno) { + ERRS("unable to write output file"); + goto out_flush; + } + + DBG("firmware file \"%s\" completed", ofname); + + ret = EXIT_SUCCESS; + +out_flush: + fflush(f); + fclose(f); + if (ret != EXIT_SUCCESS) { + unlink(ofname); + } +out: + return ret; +} + +/* Helper functions to inspect_fw() representing different output formats */ +inline void inspect_fw_pstr(const char *label, const char *str) +{ + printf("%-23s: %s\n", label, str); +} + +inline void inspect_fw_phex(const char *label, uint32_t val) +{ + printf("%-23s: 0x%08x\n", label, val); +} + +inline void inspect_fw_phexdec(const char *label, uint32_t val) +{ + printf("%-23s: 0x%08x / %8u bytes\n", label, val, val); +} + +inline void inspect_fw_pmd5sum(const char *label, const uint8_t *val, const char *text) +{ + int i; + + printf("%-23s:", label); + for (i=0; i<MD5SUM_LEN; i++) + printf(" %02x", val[i]); + printf(" %s\n", text); +} + +// header_size = sizeof(struct fw_header) +int build_fw(size_t header_size) +{ + int buflen; + char *buf; + char *p; + int ret = EXIT_FAILURE; + int writelen = 0; + + writelen = header_size + kernel_len; + + if (combined) + buflen = writelen; + else + buflen = layout->fw_max_len; + + buf = malloc(buflen); + if (!buf) { + ERR("no memory for buffer\n"); + goto out; + } + + memset(buf, 0xff, buflen); + p = buf + header_size; + ret = read_to_buf(&kernel_info, p); + if (ret) + goto out_free_buf; + + if (!combined) { + p = buf + rootfs_ofs; + + ret = read_to_buf(&rootfs_info, p); + if (ret) + goto out_free_buf; + + writelen = rootfs_ofs + rootfs_info.file_size; + + if (add_jffs2_eof) + writelen = pad_jffs2(buf, writelen, layout->fw_max_len); + } + + if (!strip_padding) + writelen = buflen; + + fill_header(buf, writelen); + ret = write_fw(ofname, buf, writelen); + if (ret) + goto out_free_buf; + + ret = EXIT_SUCCESS; + +out_free_buf: + free(buf); +out: + return ret; +} diff --git a/tools/firmware-utils/src/mktplinkfw-lib.h b/tools/firmware-utils/src/mktplinkfw-lib.h new file mode 100644 index 00000000000..31e6d0b1e6b --- /dev/null +++ b/tools/firmware-utils/src/mktplinkfw-lib.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> + * + * This tool was based on: + * TP-Link WR941 V2 firmware checksum fixing tool. + * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + + +#ifndef mktplinkfw_lib_h +#define mktplinkfw_lib_h + +#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); }) +#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0])) + +#define MD5SUM_LEN 16 + +/* + * Message macros + */ +#define ERR(fmt, ...) do { \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt "\n", \ + progname, ## __VA_ARGS__ ); \ +} while (0) + +#define ERRS(fmt, ...) do { \ + int save = errno; \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ + progname, ## __VA_ARGS__, strerror(save)); \ +} while (0) + +#define DBG(fmt, ...) do { \ + fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ +} while (0) + + +struct file_info { + char *file_name; /* name of the file */ + uint32_t file_size; /* length of the file */ +}; + +struct flash_layout { + char *id; + uint32_t fw_max_len; + uint32_t kernel_la; + uint32_t kernel_ep; + uint32_t rootfs_ofs; +}; + +struct flash_layout *find_layout(struct flash_layout *layouts, const char *id); +void get_md5(const char *data, int size, uint8_t *md5); +int get_file_stat(struct file_info *fdata); +int read_to_buf(const struct file_info *fdata, char *buf); +int write_fw(const char *ofname, const char *data, int len); +inline void inspect_fw_pstr(const char *label, const char *str); +inline void inspect_fw_phex(const char *label, uint32_t val); +inline void inspect_fw_phexdec(const char *label, uint32_t val); +inline void inspect_fw_pmd5sum(const char *label, const uint8_t *val, const char *text); +int build_fw(size_t header_size); + +#endif /* mktplinkfw_lib_h */ diff --git a/tools/firmware-utils/src/mktplinkfw.c b/tools/firmware-utils/src/mktplinkfw.c index f8fa2f14b40..ce2acc20c93 100644 --- a/tools/firmware-utils/src/mktplinkfw.c +++ b/tools/firmware-utils/src/mktplinkfw.c @@ -19,6 +19,8 @@ #include <libgen.h> #include <getopt.h> /* for getopt() */ #include <stdarg.h> +#include <stdbool.h> +#include <endian.h> #include <errno.h> #include <sys/stat.h> @@ -26,37 +28,10 @@ #include <netinet/in.h> #include "md5.h" - -#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); }) +#include "mktplinkfw-lib.h" #define HEADER_VERSION_V1 0x01000000 -#define HWID_TL_MR3020_V1 0x30200001 -#define HWID_TL_MR3220_V1 0x32200001 -#define HWID_TL_MR3420_V1 0x34200001 -#define HWID_TL_WA701N_V1 0x07010001 -#define HWID_TL_WA901ND_V1 0x09010001 -#define HWID_TL_WA901ND_V2 0x09010002 -#define HWID_TL_WR703N_V1 0x07030101 -#define HWID_TL_WR741ND_V1 0x07410001 -#define HWID_TL_WR741ND_V4 0x07410004 -#define HWID_TL_WR740N_V1 0x07400001 -#define HWID_TL_WR740N_V3 0x07400003 -#define HWID_TL_WR743ND_V1 0x07430001 -#define HWID_TL_WR841N_V1_5 0x08410002 -#define HWID_TL_WR841ND_V3 0x08410003 -#define HWID_TL_WR841ND_V5 0x08410005 -#define HWID_TL_WR841ND_V7 0x08410007 -#define HWID_TL_WR941ND_V2 0x09410002 -#define HWID_TL_WR941ND_V4 0x09410004 -#define HWID_TL_WR1043ND_V1 0x10430001 -#define HWID_TL_WR2543N_V1 0x25430001 - -#define MD5SUM_LEN 16 - -struct file_info { - char *file_name; /* name of the file */ - uint32_t file_size; /* length of the file */ -}; +#define HEADER_VERSION_V2 0x02000000 struct fw_header { uint32_t version; /* header version */ @@ -64,7 +39,7 @@ struct fw_header { char fw_version[36]; uint32_t hw_id; /* hardware id */ uint32_t hw_rev; /* hardware revision */ - uint32_t unk1; + uint32_t region_code; /* region code */ uint8_t md5sum1[MD5SUM_LEN]; uint32_t unk2; uint8_t md5sum2[MD5SUM_LEN]; @@ -78,62 +53,68 @@ struct fw_header { uint32_t rootfs_len; /* rootfs data length */ uint32_t boot_ofs; /* bootloader data offset */ uint32_t boot_len; /* bootloader data length */ - uint8_t pad[360]; + uint16_t ver_hi; + uint16_t ver_mid; + uint16_t ver_lo; + uint8_t pad[130]; + char region_str1[32]; + char region_str2[32]; + uint8_t pad2[160]; } __attribute__ ((packed)); -struct flash_layout { - char *id; - uint32_t fw_max_len; - uint32_t kernel_la; - uint32_t kernel_ep; - uint32_t rootfs_ofs; +struct fw_region { + char name[4]; + uint32_t code; }; -struct board_info { - char *id; - uint32_t hw_id; - uint32_t hw_rev; - char *layout_id; -}; /* * Globals */ -static char *ofname; -static char *progname; +char *ofname; +char *progname; static char *vendor = "TP-LINK Technologies"; static char *version = "ver. 1.0"; +static char *fw_ver = "0.0.0"; +static uint32_t hdr_ver = HEADER_VERSION_V1; -static char *board_id; -static struct board_info *board; static char *layout_id; -static struct flash_layout *layout; +struct flash_layout *layout; static char *opt_hw_id; static uint32_t hw_id; static char *opt_hw_rev; static uint32_t hw_rev; -static struct file_info kernel_info; +static uint32_t opt_hdr_ver = 1; +static char *country; +static const struct fw_region *region; +static int fw_ver_lo; +static int fw_ver_mid; +static int fw_ver_hi; +struct file_info kernel_info; static uint32_t kernel_la = 0; static uint32_t kernel_ep = 0; -static uint32_t kernel_len = 0; -static struct file_info rootfs_info; -static uint32_t rootfs_ofs = 0; -static uint32_t rootfs_align; +uint32_t kernel_len = 0; +struct file_info rootfs_info; +uint32_t rootfs_ofs = 0; +uint32_t rootfs_align; static struct file_info boot_info; -static int combined; -static int strip_padding; -static int add_jffs2_eof; -static unsigned char jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde}; +int combined; +int strip_padding; +int add_jffs2_eof; +static uint32_t fw_max_len; +static uint32_t reserved_space; static struct file_info inspect_info; static int extract = 0; +static bool endian_swap = false; +static bool rootfs_ofs_calc = false; -char md5salt_normal[MD5SUM_LEN] = { +static const char md5salt_normal[MD5SUM_LEN] = { 0xdc, 0xd7, 0x3a, 0xa5, 0xc3, 0x95, 0x98, 0xfb, 0xdd, 0xf9, 0xe7, 0xf4, 0x0e, 0xae, 0x47, 0x38, }; -char md5salt_boot[MD5SUM_LEN] = { +static const char md5salt_boot[MD5SUM_LEN] = { 0x8c, 0xef, 0x33, 0x5b, 0xd5, 0xc5, 0xce, 0xfa, 0xa7, 0x9c, 0x28, 0xda, 0xb2, 0xe9, 0x0f, 0x42, }; @@ -164,268 +145,85 @@ static struct flash_layout layouts[] = { .kernel_ep = 0x80060000, .rootfs_ofs = 0x100000, }, { - /* terminating entry */ - } -}; - -static struct board_info boards[] = { - { - .id = "TL-MR3020v1", - .hw_id = HWID_TL_MR3020_V1, - .hw_rev = 1, - .layout_id = "4Mlzma", - }, { - .id = "TL-MR3220v1", - .hw_id = HWID_TL_MR3220_V1, - .hw_rev = 1, - .layout_id = "4M", - }, { - .id = "TL-MR3420v1", - .hw_id = HWID_TL_MR3420_V1, - .hw_rev = 1, - .layout_id = "4M", - }, { - .id = "TL-WA701Nv1", - .hw_id = HWID_TL_WA701N_V1, - .hw_rev = 1, - .layout_id = "4M", - }, { - .id = "TL-WA901NDv1", - .hw_id = HWID_TL_WA901ND_V1, - .hw_rev = 1, - .layout_id = "4M", - }, { - .id = "TL-WA901NDv2", - .hw_id = HWID_TL_WA901ND_V2, - .hw_rev = 1, - .layout_id = "4M", - }, { - .id = "TL-WR741NDv1", - .hw_id = HWID_TL_WR741ND_V1, - .hw_rev = 1, - .layout_id = "4M", - }, { - .id = "TL-WR741NDv4", - .hw_id = HWID_TL_WR741ND_V4, - .hw_rev = 1, - .layout_id = "4Mlzma", - }, { - .id = "TL-WR740Nv1", - .hw_id = HWID_TL_WR740N_V1, - .hw_rev = 1, - .layout_id = "4M", - }, { - .id = "TL-WR740Nv3", - .hw_id = HWID_TL_WR740N_V3, - .hw_rev = 1, - .layout_id = "4M", - }, { - .id = "TL-WR743NDv1", - .hw_id = HWID_TL_WR743ND_V1, - .hw_rev = 1, - .layout_id = "4M", - }, { - .id = "TL-WR841Nv1.5", - .hw_id = HWID_TL_WR841N_V1_5, - .hw_rev = 2, - .layout_id = "4M", - }, { - .id = "TL-WR841NDv3", - .hw_id = HWID_TL_WR841ND_V3, - .hw_rev = 3, - .layout_id = "4M", - }, { - .id = "TL-WR841NDv5", - .hw_id = HWID_TL_WR841ND_V5, - .hw_rev = 1, - .layout_id = "4M", - }, { - .id = "TL-WR841NDv7", - .hw_id = HWID_TL_WR841ND_V7, - .hw_rev = 1, - .layout_id = "4M", - }, { - .id = "TL-WR941NDv2", - .hw_id = HWID_TL_WR941ND_V2, - .hw_rev = 2, - .layout_id = "4M", - }, { - .id = "TL-WR941NDv4", - .hw_id = HWID_TL_WR941ND_V4, - .hw_rev = 1, - .layout_id = "4M", - }, { - .id = "TL-WR1043NDv1", - .hw_id = HWID_TL_WR1043ND_V1, - .hw_rev = 1, - .layout_id = "8M", + .id = "16M", + .fw_max_len = 0xf80000, + .kernel_la = 0x80060000, + .kernel_ep = 0x80060000, + .rootfs_ofs = 0x140000, }, { - .id = "TL-WR2543Nv1", - .hw_id = HWID_TL_WR2543N_V1, - .hw_rev = 1, - .layout_id = "8Mlzma", + .id = "16Mlzma", + .fw_max_len = 0xf80000, + .kernel_la = 0x80060000, + .kernel_ep = 0x80060000, + .rootfs_ofs = 0x100000, }, { - .id = "TL-WR703Nv1", - .hw_id = HWID_TL_WR703N_V1, - .hw_rev = 1, - .layout_id = "4Mlzma", + .id = "16Mppc", + .fw_max_len = 0xf80000, + .kernel_la = 0x00000000 , + .kernel_ep = 0xc0000000, + .rootfs_ofs = 0x2a0000, }, { /* terminating entry */ } }; -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -#define DBG(fmt, ...) do { \ - fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ -} while (0) - -static struct board_info *find_board(char *id) -{ - struct board_info *ret; - struct board_info *board; - - ret = NULL; - for (board = boards; board->id != NULL; board++){ - if (strcasecmp(id, board->id) == 0) { - ret = board; - break; - } - }; - - return ret; -} +static const struct fw_region regions[] = { + /* Default region (universal) uses code 0 as well */ + {"US", 1}, + {"EU", 0}, + {"BR", 0}, +}; -static struct board_info *find_board_by_hwid(uint32_t hw_id) -{ - struct board_info *board; +static const struct fw_region * find_region(const char *country) { + size_t i; - for (board = boards; board->id != NULL; board++) { - if (hw_id == board->hw_id) - return board; - }; + for (i = 0; i < ARRAY_SIZE(regions); i++) { + if (strcasecmp(regions[i].name, country) == 0) + return ®ions[i]; + } return NULL; } -static struct flash_layout *find_layout(char *id) -{ - struct flash_layout *ret; - struct flash_layout *l; - - ret = NULL; - for (l = layouts; l->id != NULL; l++){ - if (strcasecmp(id, l->id) == 0) { - ret = l; - break; - } - }; - - return ret; -} - static void usage(int status) { - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - struct board_info *board; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, + fprintf(stderr, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stderr, "\n" "Options:\n" -" -B <board> create image for the board specified with <board>\n" " -c use combined kernel image\n" +" -e swap endianness in kernel load address and entry point\n" " -E <ep> overwrite kernel entry point with <ep> (hexval prefixed with 0x)\n" " -L <la> overwrite kernel load address with <la> (hexval prefixed with 0x)\n" " -H <hwid> use hardware id specified with <hwid>\n" +" -W <hwrev> use hardware revision specified with <hwrev>\n" +" -C <country> set region code to <country>\n" " -F <id> use flash layout specified with <id>\n" " -k <file> read kernel image from the file <file>\n" " -r <file> read rootfs image from the file <file>\n" " -a <align> align the rootfs start on an <align> bytes boundary\n" " -R <offset> overwrite rootfs offset with <offset> (hexval prefixed with 0x)\n" +" -O calculate rootfs offset for combined images\n" " -o <file> write output to the file <file>\n" " -s strip padding from the end of the image\n" " -j add jffs2 end-of-filesystem markers\n" " -N <vendor> set image vendor to <vendor>\n" " -V <version> set image version to <version>\n" +" -v <version> set firmware version to <version>\n" +" -m <version> set header version to <version>\n" " -i <file> inspect given firmware file <file>\n" " -x extract kernel and rootfs while inspecting (requires -i)\n" +" -X <size> reserve <size> bytes in the firmware image (hexval prefixed with 0x)\n" " -h show this screen\n" ); exit(status); } -static int get_md5(char *data, int size, char *md5) -{ - MD5_CTX ctx; - - MD5_Init(&ctx); - MD5_Update(&ctx, data, size); - MD5_Final(md5, &ctx); -} - -static int get_file_stat(struct file_info *fdata) -{ - struct stat st; - int res; - - if (fdata->file_name == NULL) - return 0; - - res = stat(fdata->file_name, &st); - if (res){ - ERRS("stat failed on %s", fdata->file_name); - return res; - } - - fdata->file_size = st.st_size; - return 0; -} - -static int read_to_buf(struct file_info *fdata, char *buf) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(fdata->file_name, "r"); - if (f == NULL) { - ERRS("could not open \"%s\" for reading", fdata->file_name); - goto out; - } - - errno = 0; - fread(buf, fdata->file_size, 1, f); - if (errno != 0) { - ERRS("unable to read from file \"%s\"", fdata->file_name); - goto out_close; - } - - ret = EXIT_SUCCESS; - - out_close: - fclose(f); - out: - return ret; -} - static int check_options(void) { int ret; + int exceed_bytes; if (inspect_info.file_name) { ret = get_file_stat(&inspect_info); @@ -438,48 +236,55 @@ static int check_options(void) return -1; } - if (board_id == NULL && opt_hw_id == NULL) { - ERR("either board or hardware id must be specified"); + if (opt_hw_id == NULL) { + ERR("hardware id not specified"); + return -1; + } + hw_id = strtoul(opt_hw_id, NULL, 0); + + if (!combined && layout_id == NULL) { + ERR("flash layout is not specified"); return -1; } - if (board_id) { - board = find_board(board_id); - if (board == NULL) { - ERR("unknown/unsupported board id \"%s\"", board_id); + if (opt_hw_rev) + hw_rev = strtoul(opt_hw_rev, NULL, 0); + else + hw_rev = 1; + + if (country) { + region = find_region(country); + if (!region) { + ERR("unknown region code \"%s\"", country); return -1; } - if (layout_id == NULL) - layout_id = board->layout_id; + } - hw_id = board->hw_id; - hw_rev = board->hw_rev; + if (combined) { + if (!kernel_la || !kernel_ep) { + ERR("kernel loading address and entry point must be specified for combined image"); + return -1; + } } else { - if (layout_id == NULL) { - ERR("flash layout is not specified"); + layout = find_layout(layouts, layout_id); + if (layout == NULL) { + ERR("unknown flash layout \"%s\"", layout_id); return -1; } - hw_id = strtoul(opt_hw_id, NULL, 0); - if (opt_hw_rev) - hw_rev = strtoul(opt_hw_rev, NULL, 0); - else - hw_rev = 1; - } + if (!kernel_la) + kernel_la = layout->kernel_la; + if (!kernel_ep) + kernel_ep = layout->kernel_ep; + if (!rootfs_ofs) + rootfs_ofs = layout->rootfs_ofs; - layout = find_layout(layout_id); - if (layout == NULL) { - ERR("unknown flash layout \"%s\"", layout_id); - return -1; + if (reserved_space > layout->fw_max_len) { + ERR("reserved space is not valid"); + return -1; + } } - if (!kernel_la) - kernel_la = layout->kernel_la; - if (!kernel_ep) - kernel_ep = layout->kernel_ep; - if (!rootfs_ofs) - rootfs_ofs = layout->rootfs_ofs; - if (kernel_info.file_name == NULL) { ERR("no kernel image specified"); return -1; @@ -491,13 +296,9 @@ static int check_options(void) kernel_len = kernel_info.file_size; - if (combined) { - if (kernel_info.file_size > - layout->fw_max_len - sizeof(struct fw_header)) { - ERR("kernel image is too big"); - return -1; - } - } else { + if (!combined) { + fw_max_len = layout->fw_max_len - reserved_space; + if (rootfs_info.file_name == NULL) { ERR("no rootfs image specified"); return -1; @@ -509,26 +310,26 @@ static int check_options(void) if (rootfs_align) { kernel_len += sizeof(struct fw_header); - kernel_len = ALIGN(kernel_len, rootfs_align); + rootfs_ofs = ALIGN(kernel_len, rootfs_align); kernel_len -= sizeof(struct fw_header); - DBG("kernel length aligned to %u", kernel_len); + DBG("rootfs offset aligned to 0x%u", rootfs_ofs); - if (kernel_len + rootfs_info.file_size > - layout->fw_max_len - sizeof(struct fw_header)) { - ERR("images are too big"); + exceed_bytes = kernel_len + rootfs_info.file_size - (fw_max_len - sizeof(struct fw_header)); + if (exceed_bytes > 0) { + ERR("images are too big by %i bytes", exceed_bytes); return -1; } } else { - if (kernel_info.file_size > - rootfs_ofs - sizeof(struct fw_header)) { - ERR("kernel image is too big"); + exceed_bytes = kernel_info.file_size - (rootfs_ofs - sizeof(struct fw_header)); + if (exceed_bytes > 0) { + ERR("kernel image is too big by %i bytes", exceed_bytes); return -1; } - if (rootfs_info.file_size > - (layout->fw_max_len - rootfs_ofs)) { - ERR("rootfs image is too big"); + exceed_bytes = rootfs_info.file_size - (fw_max_len - rootfs_ofs); + if (exceed_bytes > 0) { + ERR("rootfs image is too big by %i bytes", exceed_bytes); return -1; } } @@ -539,227 +340,79 @@ static int check_options(void) return -1; } + ret = sscanf(fw_ver, "%d.%d.%d", &fw_ver_hi, &fw_ver_mid, &fw_ver_lo); + if (ret != 3) { + ERR("invalid firmware version '%s'", fw_ver); + return -1; + } + + if (opt_hdr_ver == 1) { + hdr_ver = HEADER_VERSION_V1; + } else if (opt_hdr_ver == 2) { + hdr_ver = HEADER_VERSION_V2; + } else { + ERR("invalid header version '%u'", opt_hdr_ver); + return -1; + } + return 0; } -static void fill_header(char *buf, int len) +void fill_header(char *buf, int len) { struct fw_header *hdr = (struct fw_header *)buf; memset(hdr, 0, sizeof(struct fw_header)); - hdr->version = htonl(HEADER_VERSION_V1); + hdr->version = htonl(hdr_ver); strncpy(hdr->vendor_name, vendor, sizeof(hdr->vendor_name)); strncpy(hdr->fw_version, version, sizeof(hdr->fw_version)); hdr->hw_id = htonl(hw_id); hdr->hw_rev = htonl(hw_rev); - if (boot_info.file_size == 0) - memcpy(hdr->md5sum1, md5salt_normal, sizeof(hdr->md5sum1)); - else - memcpy(hdr->md5sum1, md5salt_boot, sizeof(hdr->md5sum1)); - hdr->kernel_la = htonl(kernel_la); hdr->kernel_ep = htonl(kernel_ep); - hdr->fw_length = htonl(layout->fw_max_len); hdr->kernel_ofs = htonl(sizeof(struct fw_header)); hdr->kernel_len = htonl(kernel_len); + if (!combined) { + if (boot_info.file_size == 0) + memcpy(hdr->md5sum1, md5salt_normal, sizeof(hdr->md5sum1)); + else + memcpy(hdr->md5sum1, md5salt_boot, sizeof(hdr->md5sum1)); + + hdr->fw_length = htonl(layout->fw_max_len); hdr->rootfs_ofs = htonl(rootfs_ofs); hdr->rootfs_len = htonl(rootfs_info.file_size); } - get_md5(buf, len, hdr->md5sum1); -} - -static int pad_jffs2(char *buf, int currlen) -{ - int len; - uint32_t pad_mask; - - len = currlen; - pad_mask = (64 * 1024); - while ((len < layout->fw_max_len) && (pad_mask != 0)) { - uint32_t mask; - int i; - - for (i = 10; i < 32; i++) { - mask = 1 << i; - if (pad_mask & mask) - break; - } - - len = ALIGN(len, mask); - - for (i = 10; i < 32; i++) { - mask = 1 << i; - if ((len & (mask - 1)) == 0) - pad_mask &= ~mask; - } - - for (i = 0; i < sizeof(jffs2_eof_mark); i++) - buf[len + i] = jffs2_eof_mark[i]; - - len += sizeof(jffs2_eof_mark); - } - - return len; -} - -static int write_fw(char *data, int len) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(ofname, "w"); - if (f == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto out; - } - - errno = 0; - fwrite(data, len, 1, f); - if (errno) { - ERRS("unable to write output file"); - goto out_flush; - } - - DBG("firmware file \"%s\" completed", ofname); - - ret = EXIT_SUCCESS; - - out_flush: - fflush(f); - fclose(f); - if (ret != EXIT_SUCCESS) { - unlink(ofname); + if (combined && rootfs_ofs_calc) { + hdr->rootfs_ofs = htonl(sizeof(struct fw_header) + kernel_len); } - out: - return ret; -} -static int build_fw(void) -{ - int buflen; - char *buf; - char *p; - int ret = EXIT_FAILURE; - int writelen = 0; - - buflen = layout->fw_max_len; - - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto out; + hdr->ver_hi = htons(fw_ver_hi); + hdr->ver_mid = htons(fw_ver_mid); + hdr->ver_lo = htons(fw_ver_lo); + + if (region) { + hdr->region_code = htonl(region->code); + snprintf( + hdr->region_str1, sizeof(hdr->region_str1), "00000000;%02X%02X%02X%02X;", + region->name[0], region->name[1], region->name[2], region->name[3] + ); + snprintf( + hdr->region_str2, sizeof(hdr->region_str2), "%02X%02X%02X%02X", + region->name[0], region->name[1], region->name[2], region->name[3] + ); } - memset(buf, 0xff, buflen); - p = buf + sizeof(struct fw_header); - ret = read_to_buf(&kernel_info, p); - if (ret) - goto out_free_buf; - - writelen = sizeof(struct fw_header) + kernel_len; - - if (!combined) { - if (rootfs_align) - p = buf + writelen; - else - p = buf + rootfs_ofs; - - ret = read_to_buf(&rootfs_info, p); - if (ret) - goto out_free_buf; - - if (rootfs_align) - writelen += rootfs_info.file_size; - else - writelen = rootfs_ofs + rootfs_info.file_size; - - if (add_jffs2_eof) - writelen = pad_jffs2(buf, writelen); + if (endian_swap) { + hdr->kernel_la = bswap_32(hdr->kernel_la); + hdr->kernel_ep = bswap_32(hdr->kernel_ep); } - if (!strip_padding) - writelen = buflen; - - fill_header(buf, writelen); - ret = write_fw(buf, writelen); - if (ret) - goto out_free_buf; - - ret = EXIT_SUCCESS; - - out_free_buf: - free(buf); - out: - return ret; -} - -/* Helper functions to inspect_fw() representing different output formats */ -static inline void inspect_fw_pstr(char *label, char *str) -{ - printf("%-23s: %s\n", label, str); -} - -static inline void inspect_fw_phex(char *label, uint32_t val) -{ - printf("%-23s: 0x%08x\n", label, val); -} - -static inline void inspect_fw_phexpost(char *label, - uint32_t val, char *post) -{ - printf("%-23s: 0x%08x (%s)\n", label, val, post); -} - -static inline void inspect_fw_phexdef(char *label, - uint32_t val, uint32_t defval) -{ - printf("%-23s: 0x%08x ", label, val); - - if (val == defval) - printf("(== OpenWrt default)\n"); - else - printf("(OpenWrt default: 0x%08x)\n", defval); -} - -static inline void inspect_fw_phexexp(char *label, - uint32_t val, uint32_t expval) -{ - printf("%-23s: 0x%08x ", label, val); - - if (val == expval) - printf("(ok)\n"); - else - printf("(expected: 0x%08x)\n", expval); -} - -static inline void inspect_fw_phexdec(char *label, uint32_t val) -{ - printf("%-23s: 0x%08x / %8u bytes\n", label, val, val); -} - -static inline void inspect_fw_phexdecdef(char *label, - uint32_t val, uint32_t defval) -{ - printf("%-23s: 0x%08x / %8u bytes ", label, val, val); - - if (val == defval) - printf("(== OpenWrt default)\n"); - else - printf("(OpenWrt default: 0x%08x)\n", defval); -} - -static inline void inspect_fw_pmd5sum(char *label, uint8_t *val, char *text) -{ - int i; - - printf("%-23s:", label); - for (i=0; i<MD5SUM_LEN; i++) - printf(" %02x", val[i]); - printf(" %s\n", text); + if (!combined) + get_md5(buf, len, hdr->md5sum1); } static int inspect_fw(void) @@ -767,7 +420,6 @@ static int inspect_fw(void) char *buf; struct fw_header *hdr; uint8_t md5sum[MD5SUM_LEN]; - struct board_info *board; int ret = EXIT_FAILURE; buf = malloc(inspect_info.file_size); @@ -784,16 +436,14 @@ static int inspect_fw(void) inspect_fw_pstr("File name", inspect_info.file_name); inspect_fw_phexdec("File size", inspect_info.file_size); - if (ntohl(hdr->version) != HEADER_VERSION_V1) { - ERR("file does not seem to have V1 header!\n"); + if ((ntohl(hdr->version) != HEADER_VERSION_V1) && + (ntohl(hdr->version) != HEADER_VERSION_V2)) { + ERR("file does not seem to have V1/V2 header!\n"); goto out_free_buf; } inspect_fw_phexdec("Version 1 Header size", sizeof(struct fw_header)); - if (ntohl(hdr->unk1) != 0) - inspect_fw_phexdec("Unknown value 1", hdr->unk1); - memcpy(md5sum, hdr->md5sum1, sizeof(md5sum)); if (ntohl(hdr->boot_len) == 0) memcpy(hdr->md5sum1, md5salt_normal, sizeof(md5sum)); @@ -818,19 +468,9 @@ static int inspect_fw(void) inspect_fw_pstr("Vendor name", hdr->vendor_name); inspect_fw_pstr("Firmware version", hdr->fw_version); - board = find_board_by_hwid(ntohl(hdr->hw_id)); - if (board) { - layout = find_layout(board->layout_id); - inspect_fw_phexpost("Hardware ID", - ntohl(hdr->hw_id), board->id); - inspect_fw_phexexp("Hardware Revision", - ntohl(hdr->hw_rev), board->hw_rev); - } else { - inspect_fw_phexpost("Hardware ID", - ntohl(hdr->hw_id), "unknown"); - inspect_fw_phex("Hardware Revision", - ntohl(hdr->hw_rev)); - } + inspect_fw_phex("Hardware ID", ntohl(hdr->hw_id)); + inspect_fw_phex("Hardware Revision", ntohl(hdr->hw_rev)); + inspect_fw_phex("Region code", ntohl(hdr->region_code)); printf("\n"); @@ -838,24 +478,12 @@ static int inspect_fw(void) ntohl(hdr->kernel_ofs)); inspect_fw_phexdec("Kernel data length", ntohl(hdr->kernel_len)); - if (board) { - inspect_fw_phexdef("Kernel load address", - ntohl(hdr->kernel_la), - layout ? layout->kernel_la : 0xffffffff); - inspect_fw_phexdef("Kernel entry point", - ntohl(hdr->kernel_ep), - layout ? layout->kernel_ep : 0xffffffff); - inspect_fw_phexdecdef("Rootfs data offset", - ntohl(hdr->rootfs_ofs), - layout ? layout->rootfs_ofs : 0xffffffff); - } else { - inspect_fw_phex("Kernel load address", - ntohl(hdr->kernel_la)); - inspect_fw_phex("Kernel entry point", - ntohl(hdr->kernel_ep)); - inspect_fw_phexdec("Rootfs data offset", - ntohl(hdr->rootfs_ofs)); - } + inspect_fw_phex("Kernel load address", + ntohl(hdr->kernel_la)); + inspect_fw_phex("Kernel entry point", + ntohl(hdr->kernel_ep)); + inspect_fw_phexdec("Rootfs data offset", + ntohl(hdr->rootfs_ofs)); inspect_fw_phexdec("Rootfs data length", ntohl(hdr->rootfs_len)); inspect_fw_phexdec("Boot loader data offset", @@ -911,16 +539,13 @@ static int inspect_fw(void) int main(int argc, char *argv[]) { int ret = EXIT_FAILURE; - int err; - - FILE *outfile; progname = basename(argv[0]); while ( 1 ) { int c; - c = getopt(argc, argv, "a:B:H:E:F:L:V:N:W:ci:k:r:R:o:xhsj"); + c = getopt(argc, argv, "a:H:E:F:L:m:V:N:W:C:ci:k:r:R:o:OxX:ehsjv:"); if (c == -1) break; @@ -928,9 +553,6 @@ int main(int argc, char *argv[]) case 'a': sscanf(optarg, "0x%x", &rootfs_align); break; - case 'B': - board_id = optarg; - break; case 'H': opt_hw_id = optarg; break; @@ -943,12 +565,21 @@ int main(int argc, char *argv[]) case 'W': opt_hw_rev = optarg; break; + case 'C': + country = optarg; + break; case 'L': sscanf(optarg, "0x%x", &kernel_la); break; + case 'm': + sscanf(optarg, "%u", &opt_hdr_ver); + break; case 'V': version = optarg; break; + case 'v': + fw_ver = optarg; + break; case 'N': vendor = optarg; break; @@ -967,6 +598,9 @@ int main(int argc, char *argv[]) case 'o': ofname = optarg; break; + case 'O': + rootfs_ofs_calc = 1; + break; case 's': strip_padding = 1; break; @@ -979,9 +613,15 @@ int main(int argc, char *argv[]) case 'x': extract = 1; break; + case 'e': + endian_swap = true; + break; case 'h': usage(EXIT_SUCCESS); break; + case 'X': + sscanf(optarg, "0x%x", &reserved_space); + break; default: usage(EXIT_FAILURE); break; @@ -993,11 +633,10 @@ int main(int argc, char *argv[]) goto out; if (!inspect_info.file_name) - ret = build_fw(); + ret = build_fw(sizeof(struct fw_header)); else ret = inspect_fw(); out: return ret; } - diff --git a/tools/firmware-utils/src/mktplinkfw2.c b/tools/firmware-utils/src/mktplinkfw2.c new file mode 100644 index 00000000000..dead49e7af8 --- /dev/null +++ b/tools/firmware-utils/src/mktplinkfw2.c @@ -0,0 +1,628 @@ +/* + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> + * + * This tool was based on: + * TP-Link WR941 V2 firmware checksum fixing tool. + * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> /* for unlink() */ +#include <libgen.h> +#include <getopt.h> /* for getopt() */ +#include <stdarg.h> +#include <errno.h> +#include <stdbool.h> +#include <endian.h> +#include <sys/stat.h> + +#include <arpa/inet.h> +#include <netinet/in.h> + +#include "md5.h" +#include "mktplinkfw-lib.h" + +struct fw_header { + uint32_t version; /* 0x00: header version */ + char fw_version[48]; /* 0x04: fw version string */ + uint32_t hw_id; /* 0x34: hardware id */ + uint32_t hw_rev; /* 0x38: FIXME: hardware revision? */ + uint32_t hw_ver_add; /* 0x3c: additional hardware version */ + uint8_t md5sum1[MD5SUM_LEN]; /* 0x40 */ + uint32_t unk2; /* 0x50: 0x00000000 */ + uint8_t md5sum2[MD5SUM_LEN]; /* 0x54 */ + uint32_t unk3; /* 0x64: 0xffffffff */ + + uint32_t kernel_la; /* 0x68: kernel load address */ + uint32_t kernel_ep; /* 0x6c: kernel entry point */ + uint32_t fw_length; /* 0x70: total length of the image */ + uint32_t kernel_ofs; /* 0x74: kernel data offset */ + uint32_t kernel_len; /* 0x78: kernel data length */ + uint32_t rootfs_ofs; /* 0x7c: rootfs data offset */ + uint32_t rootfs_len; /* 0x80: rootfs data length */ + uint32_t boot_ofs; /* 0x84: bootloader offset */ + uint32_t boot_len; /* 0x88: bootloader length */ + uint16_t unk4; /* 0x8c: 0x55aa */ + uint8_t sver_hi; /* 0x8e */ + uint8_t sver_lo; /* 0x8f */ + uint8_t unk5; /* 0x90: magic: 0xa5 */ + uint8_t ver_hi; /* 0x91 */ + uint8_t ver_mid; /* 0x92 */ + uint8_t ver_lo; /* 0x93 */ + uint8_t pad[364]; +} __attribute__ ((packed)); + +#define FLAG_LE_KERNEL_LA_EP 0x00000001 /* Little-endian used for kernel load address & entry point */ + +struct board_info { + char *id; + uint32_t hw_id; + uint32_t hw_rev; + uint32_t hw_ver_add; + char *layout_id; + uint32_t hdr_ver; + uint32_t flags; +}; + +/* + * Globals + */ +char *ofname; +char *progname; +static char *vendor = "TP-LINK Technologies"; +static char *version = "ver. 1.0"; +static char *fw_ver = "0.0.0"; +static char *sver = "1.0"; +static uint32_t hdr_ver = 2; + +static struct board_info custom_board; + +static struct board_info *board; +static char *layout_id; +struct flash_layout *layout; +static char *opt_hw_id; +static char *opt_hw_rev; +static char *opt_hw_ver_add; +static int fw_ver_lo; +static int fw_ver_mid; +static int fw_ver_hi; +static int sver_lo; +static int sver_hi; +struct file_info kernel_info; +static uint32_t kernel_la = 0; +static uint32_t kernel_ep = 0; +uint32_t kernel_len = 0; +struct file_info rootfs_info; +uint32_t rootfs_ofs = 0; +uint32_t rootfs_align; +static struct file_info boot_info; +int combined; +int strip_padding; +int add_jffs2_eof; + +static struct file_info inspect_info; +static int extract = 0; + +char md5salt_normal[MD5SUM_LEN] = { + 0xdc, 0xd7, 0x3a, 0xa5, 0xc3, 0x95, 0x98, 0xfb, + 0xdc, 0xf9, 0xe7, 0xf4, 0x0e, 0xae, 0x47, 0x37, +}; + +char md5salt_boot[MD5SUM_LEN] = { + 0x8c, 0xef, 0x33, 0x5f, 0xd5, 0xc5, 0xce, 0xfa, + 0xac, 0x9c, 0x28, 0xda, 0xb2, 0xe9, 0x0f, 0x42, +}; + +static struct flash_layout layouts[] = { + { + .id = "4Mmtk", + .fw_max_len = 0x3d0000, + .kernel_la = 0x80000000, + .kernel_ep = 0x80000000, + .rootfs_ofs = 0x140000, + }, { + .id = "8Mltq", + .fw_max_len = 0x7a0000, + .kernel_la = 0x80002000, + .kernel_ep = 0x80002000, + .rootfs_ofs = 0x140000, + }, { + .id = "16Mltq", + .fw_max_len = 0xf90000, + .kernel_la = 0x80002000, + .kernel_ep = 0x800061b0, + .rootfs_ofs = 0x140000, + }, { + .id = "8Mmtk", + .fw_max_len = 0x7a0000, + .kernel_la = 0x80000000, + .kernel_ep = 0x80000000, + .rootfs_ofs = 0x140000, + }, { + .id = "8MLmtk", + .fw_max_len = 0x7b0000, + .kernel_la = 0x80000000, + .kernel_ep = 0x80000000, + .rootfs_ofs = 0x140000, + }, { + /* terminating entry */ + } +}; + +static void usage(int status) +{ + FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; + struct board_info *board; + + fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stream, +"\n" +"Options:\n" +" -c use combined kernel image\n" +" -e swap endianness in kernel load address and entry point\n" +" -E <ep> overwrite kernel entry point with <ep> (hexval prefixed with 0x)\n" +" -L <la> overwrite kernel load address with <la> (hexval prefixed with 0x)\n" +" -H <hwid> use hardware id specified with <hwid>\n" +" -W <hwrev> use hardware revision specified with <hwrev>\n" +" -w <hwveradd> use additional hardware version specified with <hwveradd>\n" +" -F <id> use flash layout specified with <id>\n" +" -k <file> read kernel image from the file <file>\n" +" -r <file> read rootfs image from the file <file>\n" +" -a <align> align the rootfs start on an <align> bytes boundary\n" +" -R <offset> overwrite rootfs offset with <offset> (hexval prefixed with 0x)\n" +" -o <file> write output to the file <file>\n" +" -s strip padding from the end of the image\n" +" -j add jffs2 end-of-filesystem markers\n" +" -N <vendor> set image vendor to <vendor>\n" +" -T <version> set header version to <version>\n" +" -V <version> set image version to <version>\n" +" -v <version> set firmware version to <version>\n" +" -y <version> set secondary version to <version>\n" +" -i <file> inspect given firmware file <file>\n" +" -x extract kernel and rootfs while inspecting (requires -i)\n" +" -h show this screen\n" + ); + + exit(status); +} + +static int check_options(void) +{ + int ret; + + if (inspect_info.file_name) { + ret = get_file_stat(&inspect_info); + if (ret) + return ret; + + return 0; + } else if (extract) { + ERR("no firmware for inspection specified"); + return -1; + } + + if (opt_hw_id == NULL) { + ERR("hardware id must be specified"); + return -1; + } + + board = &custom_board; + + if (layout_id == NULL) { + ERR("flash layout is not specified"); + return -1; + } + + board->hw_id = strtoul(opt_hw_id, NULL, 0); + + board->hw_rev = 1; + board->hw_ver_add = 0; + + if (opt_hw_rev) + board->hw_rev = strtoul(opt_hw_rev, NULL, 0); + if (opt_hw_ver_add) + board->hw_ver_add = strtoul(opt_hw_ver_add, NULL, 0); + + layout = find_layout(layouts, layout_id); + if (layout == NULL) { + ERR("unknown flash layout \"%s\"", layout_id); + return -1; + } + + if (!kernel_la) + kernel_la = layout->kernel_la; + if (!kernel_ep) + kernel_ep = layout->kernel_ep; + if (!rootfs_ofs) + rootfs_ofs = layout->rootfs_ofs; + + if (kernel_info.file_name == NULL) { + ERR("no kernel image specified"); + return -1; + } + + ret = get_file_stat(&kernel_info); + if (ret) + return ret; + + kernel_len = kernel_info.file_size; + + if (combined) { + if (kernel_info.file_size > + layout->fw_max_len - sizeof(struct fw_header)) { + ERR("kernel image is too big"); + return -1; + } + } else { + if (rootfs_info.file_name == NULL) { + ERR("no rootfs image specified"); + return -1; + } + + ret = get_file_stat(&rootfs_info); + if (ret) + return ret; + + if (rootfs_align) { + kernel_len += sizeof(struct fw_header); + rootfs_ofs = ALIGN(kernel_len, rootfs_align); + kernel_len -= sizeof(struct fw_header); + + DBG("rootfs offset aligned to 0x%u", rootfs_ofs); + + if (kernel_len + rootfs_info.file_size > + layout->fw_max_len - sizeof(struct fw_header)) { + ERR("images are too big"); + return -1; + } + } else { + if (kernel_info.file_size > + rootfs_ofs - sizeof(struct fw_header)) { + ERR("kernel image is too big"); + return -1; + } + + if (rootfs_info.file_size > + (layout->fw_max_len - rootfs_ofs)) { + ERR("rootfs image is too big"); + return -1; + } + } + } + + if (ofname == NULL) { + ERR("no output file specified"); + return -1; + } + + ret = sscanf(fw_ver, "%d.%d.%d", &fw_ver_hi, &fw_ver_mid, &fw_ver_lo); + if (ret != 3) { + ERR("invalid firmware version '%s'", fw_ver); + return -1; + } + + ret = sscanf(sver, "%d.%d", &sver_hi, &sver_lo); + if (ret != 2) { + ERR("invalid secondary version '%s'", sver); + return -1; + } + + return 0; +} + +void fill_header(char *buf, int len) +{ + struct fw_header *hdr = (struct fw_header *)buf; + unsigned ver_len; + + memset(hdr, '\xff', sizeof(struct fw_header)); + + hdr->version = htonl(bswap_32(hdr_ver)); + ver_len = strlen(version); + if (ver_len > (sizeof(hdr->fw_version) - 1)) + ver_len = sizeof(hdr->fw_version) - 1; + + memcpy(hdr->fw_version, version, ver_len); + hdr->fw_version[ver_len] = 0; + + hdr->hw_id = htonl(board->hw_id); + hdr->hw_rev = htonl(board->hw_rev); + hdr->hw_ver_add = htonl(board->hw_ver_add); + + if (boot_info.file_size == 0) { + memcpy(hdr->md5sum1, md5salt_normal, sizeof(hdr->md5sum1)); + hdr->boot_ofs = htonl(0); + hdr->boot_len = htonl(0); + } else { + memcpy(hdr->md5sum1, md5salt_boot, sizeof(hdr->md5sum1)); + hdr->boot_ofs = htonl(rootfs_ofs + rootfs_info.file_size); + hdr->boot_len = htonl(rootfs_info.file_size); + } + + hdr->kernel_la = htonl(kernel_la); + hdr->kernel_ep = htonl(kernel_ep); + hdr->fw_length = htonl(layout->fw_max_len); + hdr->kernel_ofs = htonl(sizeof(struct fw_header)); + hdr->kernel_len = htonl(kernel_len); + if (!combined) { + hdr->rootfs_ofs = htonl(rootfs_ofs); + hdr->rootfs_len = htonl(rootfs_info.file_size); + } + + hdr->boot_ofs = htonl(0); + hdr->boot_len = htonl(boot_info.file_size); + + hdr->unk2 = htonl(0); + hdr->unk3 = htonl(0xffffffff); + hdr->unk4 = htons(0x55aa); + hdr->unk5 = 0xa5; + + hdr->sver_hi = sver_hi; + hdr->sver_lo = sver_lo; + + hdr->ver_hi = fw_ver_hi; + hdr->ver_mid = fw_ver_mid; + hdr->ver_lo = fw_ver_lo; + + if (board->flags & FLAG_LE_KERNEL_LA_EP) { + hdr->kernel_la = bswap_32(hdr->kernel_la); + hdr->kernel_ep = bswap_32(hdr->kernel_ep); + } + + get_md5(buf, len, hdr->md5sum1); +} + +static int inspect_fw(void) +{ + char *buf; + struct fw_header *hdr; + uint8_t md5sum[MD5SUM_LEN]; + struct board_info *board; + int ret = EXIT_FAILURE; + + buf = malloc(inspect_info.file_size); + if (!buf) { + ERR("no memory for buffer!\n"); + goto out; + } + + ret = read_to_buf(&inspect_info, buf); + if (ret) + goto out_free_buf; + hdr = (struct fw_header *)buf; + + board = &custom_board; + + if (board->flags & FLAG_LE_KERNEL_LA_EP) { + hdr->kernel_la = bswap_32(hdr->kernel_la); + hdr->kernel_ep = bswap_32(hdr->kernel_ep); + } + + inspect_fw_pstr("File name", inspect_info.file_name); + inspect_fw_phexdec("File size", inspect_info.file_size); + + switch(bswap_32(ntohl(hdr->version))) { + case 2: + case 3: + break; + default: + ERR("file does not seem to have V2/V3 header!\n"); + goto out_free_buf; + } + + inspect_fw_phexdec("Version 2 Header size", sizeof(struct fw_header)); + + memcpy(md5sum, hdr->md5sum1, sizeof(md5sum)); + if (ntohl(hdr->boot_len) == 0) + memcpy(hdr->md5sum1, md5salt_normal, sizeof(md5sum)); + else + memcpy(hdr->md5sum1, md5salt_boot, sizeof(md5sum)); + get_md5(buf, inspect_info.file_size, hdr->md5sum1); + + if (memcmp(md5sum, hdr->md5sum1, sizeof(md5sum))) { + inspect_fw_pmd5sum("Header MD5Sum1", md5sum, "(*ERROR*)"); + inspect_fw_pmd5sum(" --> expected", hdr->md5sum1, ""); + } else { + inspect_fw_pmd5sum("Header MD5Sum1", md5sum, "(ok)"); + } + if (ntohl(hdr->unk2) != 0) + inspect_fw_phexdec("Unknown value 2", hdr->unk2); + inspect_fw_pmd5sum("Header MD5Sum2", hdr->md5sum2, + "(purpose yet unknown, unchecked here)"); + + if (ntohl(hdr->unk3) != 0xffffffff) + inspect_fw_phexdec("Unknown value 3", hdr->unk3); + + if (ntohs(hdr->unk4) != 0x55aa) + inspect_fw_phexdec("Unknown value 4", hdr->unk4); + + if (hdr->unk5 != 0xa5) + inspect_fw_phexdec("Unknown value 5", hdr->unk5); + + printf("\n"); + + inspect_fw_pstr("Firmware version", hdr->fw_version); + inspect_fw_phex("Hardware ID", ntohl(hdr->hw_id)); + inspect_fw_phex("Hardware Revision", + ntohl(hdr->hw_rev)); + inspect_fw_phex("Additional HW Version", + ntohl(hdr->hw_ver_add)); + + printf("%-23s: %d.%d.%d-%d.%d\n", "Software version", + hdr->ver_hi, hdr->ver_mid, hdr->ver_lo, + hdr->sver_hi, hdr->sver_lo); + + printf("\n"); + + inspect_fw_phexdec("Kernel data offset", + ntohl(hdr->kernel_ofs)); + inspect_fw_phexdec("Kernel data length", + ntohl(hdr->kernel_len)); + inspect_fw_phex("Kernel load address", + ntohl(hdr->kernel_la)); + inspect_fw_phex("Kernel entry point", + ntohl(hdr->kernel_ep)); + inspect_fw_phexdec("Rootfs data offset", + ntohl(hdr->rootfs_ofs)); + inspect_fw_phexdec("Rootfs data length", + ntohl(hdr->rootfs_len)); + inspect_fw_phexdec("Boot loader data offset", + ntohl(hdr->boot_ofs)); + inspect_fw_phexdec("Boot loader data length", + ntohl(hdr->boot_len)); + inspect_fw_phexdec("Total firmware length", + ntohl(hdr->fw_length)); + + if (extract) { + FILE *fp; + char *filename; + + printf("\n"); + + filename = malloc(strlen(inspect_info.file_name) + 8); + sprintf(filename, "%s-kernel", inspect_info.file_name); + printf("Extracting kernel to \"%s\"...\n", filename); + fp = fopen(filename, "w"); + if (fp) { + if (!fwrite(buf + ntohl(hdr->kernel_ofs), + ntohl(hdr->kernel_len), 1, fp)) { + ERR("error in fwrite(): %s", strerror(errno)); + } + fclose(fp); + } else { + ERR("error in fopen(): %s", strerror(errno)); + } + free(filename); + + filename = malloc(strlen(inspect_info.file_name) + 8); + sprintf(filename, "%s-rootfs", inspect_info.file_name); + printf("Extracting rootfs to \"%s\"...\n", filename); + fp = fopen(filename, "w"); + if (fp) { + if (!fwrite(buf + ntohl(hdr->rootfs_ofs), + ntohl(hdr->rootfs_len), 1, fp)) { + ERR("error in fwrite(): %s", strerror(errno)); + } + fclose(fp); + } else { + ERR("error in fopen(): %s", strerror(errno)); + } + free(filename); + } + + out_free_buf: + free(buf); + out: + return ret; +} + +int main(int argc, char *argv[]) +{ + int ret = EXIT_FAILURE; + + progname = basename(argv[0]); + + while ( 1 ) { + int c; + + c = getopt(argc, argv, "a:H:E:F:L:V:N:W:w:ci:k:r:R:o:xhsjv:y:T:e"); + if (c == -1) + break; + + switch (c) { + case 'a': + sscanf(optarg, "0x%x", &rootfs_align); + break; + case 'H': + opt_hw_id = optarg; + break; + case 'E': + sscanf(optarg, "0x%x", &kernel_ep); + break; + case 'F': + layout_id = optarg; + break; + case 'W': + opt_hw_rev = optarg; + break; + case 'w': + opt_hw_ver_add = optarg; + break; + case 'L': + sscanf(optarg, "0x%x", &kernel_la); + break; + case 'V': + version = optarg; + break; + case 'v': + fw_ver = optarg; + break; + case 'y': + sver = optarg; + break; + case 'N': + vendor = optarg; + break; + case 'c': + combined++; + break; + case 'k': + kernel_info.file_name = optarg; + break; + case 'r': + rootfs_info.file_name = optarg; + break; + case 'R': + sscanf(optarg, "0x%x", &rootfs_ofs); + break; + case 'o': + ofname = optarg; + break; + case 's': + strip_padding = 1; + break; + case 'i': + inspect_info.file_name = optarg; + break; + case 'j': + add_jffs2_eof = 1; + break; + case 'x': + extract = 1; + break; + case 'T': + hdr_ver = atoi(optarg); + break; + case 'e': + custom_board.flags = FLAG_LE_KERNEL_LA_EP; + break; + case 'h': + usage(EXIT_SUCCESS); + break; + default: + usage(EXIT_FAILURE); + break; + } + } + + ret = check_options(); + if (ret) + goto out; + + if (!inspect_info.file_name) + ret = build_fw(sizeof(struct fw_header)); + else + ret = inspect_fw(); + + out: + return ret; +} + diff --git a/tools/firmware-utils/src/mkwrggimg.c b/tools/firmware-utils/src/mkwrggimg.c new file mode 100644 index 00000000000..9995b9a13d8 --- /dev/null +++ b/tools/firmware-utils/src/mkwrggimg.c @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2016 Stijn Tintel <stijn@linux-ipv6.be> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#define _ANSI_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> +#include <libgen.h> +#include <getopt.h> +#include <stdarg.h> +#include <errno.h> +#include <sys/stat.h> + +#include "md5.h" + +#define ERR(fmt, ...) do { \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt "\n", \ + progname, ## __VA_ARGS__ ); \ +} while (0) + +#define ERRS(fmt, ...) do { \ + int save = errno; \ + fflush(0); \ + fprintf(stderr, "[%s] *** error: " fmt ", %s\n", \ + progname, ## __VA_ARGS__, strerror(save)); \ +} while (0) + +#define WRGG03_MAGIC 0x20080321 + +struct wrgg03_header { + char signature[32]; + uint32_t magic1; + uint32_t magic2; + char version[16]; + char model[16]; + uint32_t flag[2]; + uint32_t reserve[2]; + char buildno[16]; + uint32_t size; + uint32_t offset; + char devname[32]; + char digest[16]; +} __attribute__ ((packed)); + +static char *progname; +static char *ifname; +static char *ofname; +static char *signature; +static char *version; +static char *model; +static uint32_t flag = 0; +static uint32_t reserve = 0; +static char *buildno; +static uint32_t offset; +static char *devname; +static int big_endian; + +void usage(int status) +{ + FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; + + fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); + fprintf(stream, +"\n" +"Options:\n" +" -b create image in big endian format\n" +" -B <buildno> build number\n" +" -i <file> read input from the file <file>\n" +" -d <name> set device name to <name>\n" +" -m <model> model name\n" +" -o <file> write output to the file <file>\n" +" -O <offset> set offset to <offset>\n" +" -s <sig> set image signature to <sig>\n" +" -h show this screen\n" + ); + + exit(status); +} + +static void put_u32(void *data, uint32_t val, int swap) +{ + unsigned char *p = data; + + if (swap) { + p[0] = (val >> 24) & 0xff; + p[1] = (val >> 16) & 0xff; + p[2] = (val >> 8) & 0xff; + p[3] = val & 0xff; + } else { + p[3] = (val >> 24) & 0xff; + p[2] = (val >> 16) & 0xff; + p[1] = (val >> 8) & 0xff; + p[0] = val & 0xff; + } +} + +static void get_digest(struct wrgg03_header *header, char *data, int size) +{ + MD5_CTX ctx; + + MD5_Init(&ctx); + + MD5_Update(&ctx, (char *)&header->offset, sizeof(header->offset)); + MD5_Update(&ctx, (char *)&header->devname, sizeof(header->devname)); + MD5_Update(&ctx, data, size); + + MD5_Final(header->digest, &ctx); +} + +int main(int argc, char *argv[]) +{ + struct wrgg03_header *header; + char *buf; + struct stat st; + int buflen; + int err; + int res = EXIT_FAILURE; + + FILE *outfile, *infile; + + progname = basename(argv[0]); + + while ( 1 ) { + int c; + + c = getopt(argc, argv, "bd:i:m:o:s:v:B:O:h"); + if (c == -1) + break; + + switch (c) { + case 'b': + big_endian = 1; + break; + case 'B': + buildno = optarg; + break; + case 'd': + devname = optarg; + break; + case 'i': + ifname = optarg; + break; + case 'm': + model = optarg; + break; + case 'o': + ofname = optarg; + break; + case 's': + signature = optarg; + break; + case 'v': + version = optarg; + break; + case 'O': + offset = strtoul(optarg, NULL, 0); + break; + case 'h': + usage(EXIT_SUCCESS); + break; + + default: + usage(EXIT_FAILURE); + break; + } + } + + if (signature == NULL) { + ERR("no signature specified"); + goto err; + } + + if (ifname == NULL) { + ERR("no input file specified"); + goto err; + } + + if (ofname == NULL) { + ERR("no output file specified"); + goto err; + } + + if (devname == NULL) { + ERR("no device name specified"); + goto err; + } + + if (model == NULL) { + ERR("no model name specified"); + goto err; + } + + if (buildno == NULL) { + ERR("no build number specified"); + goto err; + } + + if (version == NULL) { + ERR("no version specified"); + goto err; + } + + err = stat(ifname, &st); + if (err){ + ERRS("stat failed on %s", ifname); + goto err; + } + + buflen = st.st_size + sizeof(struct wrgg03_header); + buf = malloc(buflen); + if (!buf) { + ERR("no memory for buffer\n"); + goto err; + } + + infile = fopen(ifname, "r"); + if (infile == NULL) { + ERRS("could not open \"%s\" for reading", ifname); + goto err_free; + } + + errno = 0; + fread(buf + sizeof(struct wrgg03_header), st.st_size, 1, infile); + if (errno != 0) { + ERRS("unable to read from file %s", ifname); + goto close_in; + } + + header = (struct wrgg03_header *) buf; + memset(header, '\0', sizeof(struct wrgg03_header)); + + strncpy(header->signature, signature, sizeof(header->signature)); + put_u32(&header->magic1, WRGG03_MAGIC, 0); + put_u32(&header->magic2, WRGG03_MAGIC, 0); + strncpy(header->version, version, sizeof(header->version)); + strncpy(header->model, model, sizeof(header->model)); + put_u32(&header->flag, flag, 0); + put_u32(&header->reserve, reserve, 0); + strncpy(header->buildno, buildno, sizeof(header->buildno)); + put_u32(&header->size, st.st_size, big_endian); + put_u32(&header->offset, offset, big_endian); + strncpy(header->devname, devname, sizeof(header->devname)); + + get_digest(header, buf + sizeof(struct wrgg03_header), st.st_size); + + outfile = fopen(ofname, "w"); + if (outfile == NULL) { + ERRS("could not open \"%s\" for writing", ofname); + goto close_in; + } + + errno = 0; + fwrite(buf, buflen, 1, outfile); + if (errno) { + ERRS("unable to write to file %s", ofname); + goto close_out; + } + + fflush(outfile); + + res = EXIT_SUCCESS; + +close_out: + fclose(outfile); + if (res != EXIT_SUCCESS) + unlink(ofname); +close_in: + fclose(infile); +err_free: + free(buf); +err: + return res; +} diff --git a/tools/firmware-utils/src/mkzcfw.c b/tools/firmware-utils/src/mkzcfw.c index 7674e706c99..2326f1ff5c5 100644 --- a/tools/firmware-utils/src/mkzcfw.c +++ b/tools/firmware-utils/src/mkzcfw.c @@ -100,7 +100,7 @@ static struct board_info boards[] = { #define ERRS(fmt, ...) do { \ int save = errno; \ fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ + fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ progname, ## __VA_ARGS__, strerror(save)); \ } while (0) diff --git a/tools/firmware-utils/src/mkzynfw.c b/tools/firmware-utils/src/mkzynfw.c index 36c176f4325..ccbabfe7f20 100644 --- a/tools/firmware-utils/src/mkzynfw.c +++ b/tools/firmware-utils/src/mkzynfw.c @@ -27,6 +27,7 @@ #if defined(__CYGWIN__) # include <byteswap.h> #endif +#include <inttypes.h> #include "zynos.h" @@ -687,7 +688,7 @@ write_out_file(FILE *outfile, char *name, size_t len, struct csum_state *css) FILE *f; int res; - DBG(2, "writing out file, name=%s, len=%d", + DBG(2, "writing out file, name=%s, len=%zu", name, len); errno = 0; @@ -988,7 +989,7 @@ calc_block_offsets(int type, uint32_t *offset) uint32_t avail; int i, res; - DBG(1,"calculating block offsets, starting with %lu", + DBG(1,"calculating block offsets, starting with %" PRIu32, *offset); res = 0; diff --git a/tools/firmware-utils/src/nand_ecc.c b/tools/firmware-utils/src/nand_ecc.c index b1e9305158c..58fb6ce0db4 100644 --- a/tools/firmware-utils/src/nand_ecc.c +++ b/tools/firmware-utils/src/nand_ecc.c @@ -2,7 +2,7 @@ * calculate ecc code for nand flash * * Copyright (C) 2008 yajin <yajin@vm-kernel.org> - * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> + * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/tools/firmware-utils/src/osbridge-crc.c b/tools/firmware-utils/src/osbridge-crc.c index f2e3920a48c..5fd236a0746 100644 --- a/tools/firmware-utils/src/osbridge-crc.c +++ b/tools/firmware-utils/src/osbridge-crc.c @@ -51,7 +51,7 @@ static char *ofname; #define ERRS(fmt, ...) do { \ int save = errno; \ fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ + fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ progname, ## __VA_ARGS__, strerror(save)); \ } while (0) diff --git a/tools/firmware-utils/src/oseama.c b/tools/firmware-utils/src/oseama.c new file mode 100644 index 00000000000..4434b11162e --- /dev/null +++ b/tools/firmware-utils/src/oseama.c @@ -0,0 +1,556 @@ +/* + * oseama + * + * Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include <byteswap.h> +#include <endian.h> +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "md5.h" + +#if !defined(__BYTE_ORDER) +#error "Unknown byte order" +#endif + +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_be32(x) (x) +#define be32_to_cpu(x) (x) +#define cpu_to_be16(x) (x) +#define be16_to_cpu(x) (x) +#elif __BYTE_ORDER == __LITTLE_ENDIAN +#define cpu_to_be32(x) bswap_32(x) +#define be32_to_cpu(x) bswap_32(x) +#define cpu_to_be16(x) bswap_16(x) +#define be16_to_cpu(x) bswap_16(x) +#else +#error "Unsupported endianness" +#endif + +#define SEAMA_MAGIC 0x5ea3a417 + +struct seama_seal_header { + uint32_t magic; + uint16_t reserved; + uint16_t metasize; + uint32_t imagesize; +} __attribute__ ((packed)); + +struct seama_entity_header { + uint32_t magic; + uint16_t reserved; + uint16_t metasize; + uint32_t imagesize; + uint8_t md5[16]; +} __attribute__ ((packed)); + +char *seama_path; +int entity_idx = -1; +char *out_path; + +static inline size_t oseama_min(size_t x, size_t y) { + return x < y ? x : y; +} + +/************************************************** + * Info + **************************************************/ + +static void oseama_info_parse_options(int argc, char **argv) { + int c; + + while ((c = getopt(argc, argv, "e:")) != -1) { + switch (c) { + case 'e': + entity_idx = atoi(optarg); + break; + } + } +} + +static int oseama_info_entities(FILE *seama) { + struct seama_entity_header hdr; + size_t bytes, metasize, imagesize; + uint8_t buf[1024]; + char *end, *tmp; + int i = 0; + int err = 0; + + while ((bytes = fread(&hdr, 1, sizeof(hdr), seama)) == sizeof(hdr)) { + if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) { + fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic)); + err = -EINVAL; + goto err_out; + } + metasize = be16_to_cpu(hdr.metasize); + imagesize = be32_to_cpu(hdr.imagesize); + + if (entity_idx >= 0 && i != entity_idx) { + fseek(seama, metasize + imagesize, SEEK_CUR); + i++; + continue; + } + + if (metasize >= sizeof(buf)) { + fprintf(stderr, "Too small buffer (%zu B) to read all meta info (%zd B)\n", sizeof(buf), metasize); + err = -EINVAL; + goto err_out; + } + + if (entity_idx < 0) + printf("\n"); + printf("Entity offset:\t%ld\n", ftell(seama) - sizeof(hdr)); + printf("Entity size:\t%zd\n", sizeof(hdr) + metasize + imagesize); + printf("Meta size:\t%zd\n", metasize); + printf("Image size:\t%zd\n", imagesize); + + bytes = fread(buf, 1, metasize, seama); + if (bytes != metasize) { + fprintf(stderr, "Couldn't read %zd B of meta\n", metasize); + err = -EIO; + goto err_out; + } + + end = (char *)&buf[metasize - 1]; + *end = '\0'; + for (tmp = (char *)buf; tmp < end && strlen(tmp); tmp += strlen(tmp) + 1) { + printf("Meta entry:\t%s\n", tmp); + } + + fseek(seama, imagesize, SEEK_CUR); + i++; + } + +err_out: + return err; +} + +static int oseama_info(int argc, char **argv) { + FILE *seama; + struct seama_seal_header hdr; + size_t bytes; + uint16_t metasize; + uint32_t imagesize; + uint8_t buf[1024]; + int err = 0; + + if (argc < 3) { + fprintf(stderr, "No Seama file passed\n"); + err = -EINVAL; + goto out; + } + seama_path = argv[2]; + + optind = 3; + oseama_info_parse_options(argc, argv); + + seama = fopen(seama_path, "r"); + if (!seama) { + fprintf(stderr, "Couldn't open %s\n", seama_path); + err = -EACCES; + goto out; + } + + bytes = fread(&hdr, 1, sizeof(hdr), seama); + if (bytes != sizeof(hdr)) { + fprintf(stderr, "Couldn't read %s header\n", seama_path); + err = -EIO; + goto err_close; + } + metasize = be16_to_cpu(hdr.metasize); + imagesize = be32_to_cpu(hdr.imagesize); + + if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) { + fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic)); + err = -EINVAL; + goto err_close; + } + + if (metasize >= sizeof(buf)) { + fprintf(stderr, "Too small buffer (%zu B) to read all meta info (%d B)\n", sizeof(buf), metasize); + err = -EINVAL; + goto err_close; + } + + if (imagesize) { + fprintf(stderr, "Invalid Seama image size: 0x%08x (should be 0)\n", imagesize); + err = -EINVAL; + goto err_close; + } + + bytes = fread(buf, 1, metasize, seama); + if (bytes != metasize) { + fprintf(stderr, "Couldn't read %d B of meta\n", metasize); + err = -EIO; + goto err_close; + } + + if (entity_idx < 0) { + char *end, *tmp; + + printf("Meta size:\t%d\n", metasize); + printf("Image size:\t%d\n", imagesize); + + end = (char *)&buf[metasize - 1]; + *end = '\0'; + for (tmp = (char *)buf; tmp < end && strlen(tmp); tmp += strlen(tmp) + 1) { + printf("Meta entry:\t%s\n", tmp); + } + } + + oseama_info_entities(seama); + +err_close: + fclose(seama); +out: + return err; +} + +/************************************************** + * Create + **************************************************/ + +static ssize_t oseama_entity_append_file(FILE *seama, const char *in_path) { + FILE *in; + size_t bytes; + ssize_t length = 0; + uint8_t buf[128]; + + in = fopen(in_path, "r"); + if (!in) { + fprintf(stderr, "Couldn't open %s\n", in_path); + return -EACCES; + } + + while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) { + if (fwrite(buf, 1, bytes, seama) != bytes) { + fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, seama_path); + length = -EIO; + break; + } + length += bytes; + } + + fclose(in); + + return length; +} + +static ssize_t oseama_entity_append_zeros(FILE *seama, size_t length) { + uint8_t *buf; + + buf = malloc(length); + if (!buf) + return -ENOMEM; + memset(buf, 0, length); + + if (fwrite(buf, 1, length, seama) != length) { + fprintf(stderr, "Couldn't write %zu B to %s\n", length, seama_path); + return -EIO; + } + + return length; +} + +static ssize_t oseama_entity_align(FILE *seama, size_t curr_offset, size_t alignment) { + if (curr_offset & (alignment - 1)) { + size_t length = alignment - (curr_offset % alignment); + + return oseama_entity_append_zeros(seama, length); + } + + return 0; +} + +static int oseama_entity_write_hdr(FILE *seama, size_t metasize, size_t imagesize) { + struct seama_entity_header hdr = {}; + uint8_t buf[128]; + size_t length = imagesize; + size_t bytes; + MD5_CTX ctx; + + fseek(seama, sizeof(hdr) + metasize, SEEK_SET); + MD5_Init(&ctx); + while ((bytes = fread(buf, 1, oseama_min(sizeof(buf), length), seama)) > 0) { + MD5_Update(&ctx, buf, bytes); + length -= bytes; + } + MD5_Final(hdr.md5, &ctx); + + hdr.magic = cpu_to_be32(SEAMA_MAGIC); + hdr.metasize = cpu_to_be16(metasize); + hdr.imagesize = cpu_to_be32(imagesize); + + fseek(seama, 0, SEEK_SET); + bytes = fwrite(&hdr, 1, sizeof(hdr), seama); + if (bytes != sizeof(hdr)) { + fprintf(stderr, "Couldn't write Seama entity header to %s\n", seama_path); + return -EIO; + } + + return 0; +} + +static int oseama_entity(int argc, char **argv) { + FILE *seama; + ssize_t sbytes; + size_t curr_offset = sizeof(struct seama_entity_header); + size_t metasize = 0, imagesize = 0; + int c; + int err = 0; + + if (argc < 3) { + fprintf(stderr, "No Seama file passed\n"); + err = -EINVAL; + goto out; + } + seama_path = argv[2]; + + seama = fopen(seama_path, "w+"); + if (!seama) { + fprintf(stderr, "Couldn't open %s\n", seama_path); + err = -EACCES; + goto out; + } + fseek(seama, curr_offset, SEEK_SET); + + optind = 3; + while ((c = getopt(argc, argv, "m:f:b:")) != -1) { + switch (c) { + case 'm': + sbytes = fwrite(optarg, 1, strlen(optarg) + 1, seama); + if (sbytes < 0) { + fprintf(stderr, "Failed to write meta %s\n", optarg); + } else { + curr_offset += sbytes; + metasize += sbytes; + } + + sbytes = oseama_entity_align(seama, curr_offset, 4); + if (sbytes < 0) { + fprintf(stderr, "Failed to append zeros\n"); + } else { + curr_offset += sbytes; + metasize += sbytes; + } + + break; + case 'f': + case 'b': + break; + } + } + + optind = 3; + while ((c = getopt(argc, argv, "m:f:b:")) != -1) { + switch (c) { + case 'm': + break; + case 'f': + sbytes = oseama_entity_append_file(seama, optarg); + if (sbytes < 0) { + fprintf(stderr, "Failed to append file %s\n", optarg); + } else { + curr_offset += sbytes; + imagesize += sbytes; + } + break; + case 'b': + sbytes = strtol(optarg, NULL, 0) - curr_offset; + if (sbytes < 0) { + fprintf(stderr, "Current Seama entity length is 0x%zx, can't pad it with zeros to 0x%lx\n", curr_offset, strtol(optarg, NULL, 0)); + } else { + sbytes = oseama_entity_append_zeros(seama, sbytes); + if (sbytes < 0) { + fprintf(stderr, "Failed to append zeros\n"); + } else { + curr_offset += sbytes; + imagesize += sbytes; + } + } + break; + } + if (err) + break; + } + + oseama_entity_write_hdr(seama, metasize, imagesize); + + fclose(seama); +out: + return err; +} + +/************************************************** + * Extract + **************************************************/ + +static void oseama_extract_parse_options(int argc, char **argv) { + int c; + + while ((c = getopt(argc, argv, "e:o:")) != -1) { + switch (c) { + case 'e': + entity_idx = atoi(optarg); + break; + case 'o': + out_path = optarg; + break; + } + } +} + +static int oseama_extract_entity(FILE *seama, FILE *out) { + struct seama_entity_header hdr; + size_t bytes, metasize, imagesize, length; + uint8_t buf[1024]; + int i = 0; + int err = 0; + + while ((bytes = fread(&hdr, 1, sizeof(hdr), seama)) == sizeof(hdr)) { + if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) { + fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic)); + err = -EINVAL; + break; + } + metasize = be16_to_cpu(hdr.metasize); + imagesize = be32_to_cpu(hdr.imagesize); + + if (i != entity_idx) { + fseek(seama, metasize + imagesize, SEEK_CUR); + i++; + continue; + } + + fseek(seama, -sizeof(hdr), SEEK_CUR); + + length = sizeof(hdr) + metasize + imagesize; + while ((bytes = fread(buf, 1, oseama_min(sizeof(buf), length), seama)) > 0) { + if (fwrite(buf, 1, bytes, out) != bytes) { + fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path); + err = -EIO; + break; + } + length -= bytes; + } + + if (length) { + fprintf(stderr, "Couldn't extract whole entity %d from %s (%zu B left)\n", entity_idx, seama_path, length); + err = -EIO; + break; + } + + break; + } + + return err; +} + +static int oseama_extract(int argc, char **argv) { + FILE *seama; + FILE *out; + struct seama_seal_header hdr; + size_t bytes; + uint16_t metasize; + int err = 0; + + if (argc < 3) { + fprintf(stderr, "No Seama file passed\n"); + err = -EINVAL; + goto out; + } + seama_path = argv[2]; + + optind = 3; + oseama_extract_parse_options(argc, argv); + if (entity_idx < 0) { + fprintf(stderr, "No entity specified\n"); + err = -EINVAL; + goto out; + } else if (!out_path) { + fprintf(stderr, "No output file specified\n"); + err = -EINVAL; + goto out; + } + + seama = fopen(seama_path, "r"); + if (!seama) { + fprintf(stderr, "Couldn't open %s\n", seama_path); + err = -EACCES; + goto out; + } + + out = fopen(out_path, "w"); + if (!out) { + fprintf(stderr, "Couldn't open %s\n", out_path); + err = -EACCES; + goto err_close_seama; + } + + bytes = fread(&hdr, 1, sizeof(hdr), seama); + if (bytes != sizeof(hdr)) { + fprintf(stderr, "Couldn't read %s header\n", seama_path); + err = -EIO; + goto err_close_out; + } + metasize = be16_to_cpu(hdr.metasize); + + fseek(seama, metasize, SEEK_CUR); + + oseama_extract_entity(seama, out); + +err_close_out: + fclose(out); +err_close_seama: + fclose(seama); +out: + return err; +} + +/************************************************** + * Start + **************************************************/ + +static void usage() { + printf("Usage:\n"); + printf("\n"); + printf("Info about Seama seal (container):\n"); + printf("\toseama info <file> [options]\n"); + printf("\t-e\t\t\t\tprint info about specified entity only\n"); + printf("\n"); + printf("Create Seama entity:\n"); + printf("\toseama entity <file> [options]\n"); + printf("\t-m meta\t\t\t\tmeta into to put in header\n"); + printf("\t-f file\t\t\t\tappend content from file\n"); + printf("\t-b offset\t\t\tappend zeros till reaching absolute offset\n"); + printf("\n"); + printf("Extract from Seama seal (container):\n"); + printf("\toseama extract <file> [options]\n"); + printf("\t-e\t\t\t\tindex of entity to extract\n"); + printf("\t-o file\t\t\t\toutput file\n"); +} + +int main(int argc, char **argv) { + if (argc > 1) { + if (!strcmp(argv[1], "info")) + return oseama_info(argc, argv); + else if (!strcmp(argv[1], "entity")) + return oseama_entity(argc, argv); + else if (!strcmp(argv[1], "extract")) + return oseama_extract(argc, argv); + } + + usage(); + return 0; +} diff --git a/tools/firmware-utils/src/otrx.c b/tools/firmware-utils/src/otrx.c new file mode 100644 index 00000000000..223e032f2b5 --- /dev/null +++ b/tools/firmware-utils/src/otrx.c @@ -0,0 +1,592 @@ +/* + * otrx + * + * Copyright (C) 2015-2017 Rafał Miłecki <zajec5@gmail.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include <byteswap.h> +#include <endian.h> +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#if !defined(__BYTE_ORDER) +#error "Unknown byte order" +#endif + +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_le32(x) bswap_32(x) +#define le32_to_cpu(x) bswap_32(x) +#elif __BYTE_ORDER == __LITTLE_ENDIAN +#define cpu_to_le32(x) (x) +#define le32_to_cpu(x) (x) +#else +#error "Unsupported endianness" +#endif + +#define TRX_MAGIC 0x30524448 +#define TRX_FLAGS_OFFSET 12 +#define TRX_MAX_PARTS 3 + +struct trx_header { + uint32_t magic; + uint32_t length; + uint32_t crc32; + uint16_t flags; + uint16_t version; + uint32_t offset[3]; +}; + +char *trx_path; +size_t trx_offset = 0; +char *partition[TRX_MAX_PARTS] = {}; + +static inline size_t otrx_min(size_t x, size_t y) { + return x < y ? x : y; +} + +/************************************************** + * CRC32 + **************************************************/ + +static const uint32_t crc32_tbl[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +uint32_t otrx_crc32(uint32_t crc, uint8_t *buf, size_t len) { + while (len) { + crc = crc32_tbl[(crc ^ *buf) & 0xff] ^ (crc >> 8); + buf++; + len--; + } + + return crc; +} + +/************************************************** + * Check + **************************************************/ + +static void otrx_check_parse_options(int argc, char **argv) { + int c; + + while ((c = getopt(argc, argv, "o:")) != -1) { + switch (c) { + case 'o': + trx_offset = atoi(optarg); + break; + } + } +} + +static int otrx_check(int argc, char **argv) { + FILE *trx; + struct trx_header hdr; + size_t bytes, length; + uint8_t buf[1024]; + uint32_t crc32; + int err = 0; + + if (argc < 3) { + fprintf(stderr, "No TRX file passed\n"); + err = -EINVAL; + goto out; + } + trx_path = argv[2]; + + optind = 3; + otrx_check_parse_options(argc, argv); + + trx = fopen(trx_path, "r"); + if (!trx) { + fprintf(stderr, "Couldn't open %s\n", trx_path); + err = -EACCES; + goto out; + } + + fseek(trx, trx_offset, SEEK_SET); + bytes = fread(&hdr, 1, sizeof(hdr), trx); + if (bytes != sizeof(hdr)) { + fprintf(stderr, "Couldn't read %s header\n", trx_path); + err = -EIO; + goto err_close; + } + + if (le32_to_cpu(hdr.magic) != TRX_MAGIC) { + fprintf(stderr, "Invalid TRX magic: 0x%08x\n", le32_to_cpu(hdr.magic)); + err = -EINVAL; + goto err_close; + } + + length = le32_to_cpu(hdr.length); + if (length < sizeof(hdr)) { + fprintf(stderr, "Length read from TRX too low (%zu B)\n", length); + err = -EINVAL; + goto err_close; + } + + crc32 = 0xffffffff; + fseek(trx, trx_offset + TRX_FLAGS_OFFSET, SEEK_SET); + length -= TRX_FLAGS_OFFSET; + while ((bytes = fread(buf, 1, otrx_min(sizeof(buf), length), trx)) > 0) { + crc32 = otrx_crc32(crc32, buf, bytes); + length -= bytes; + } + + if (length) { + fprintf(stderr, "Couldn't read last %zd B of data from %s\n", length, trx_path); + err = -EIO; + goto err_close; + } + + if (crc32 != le32_to_cpu(hdr.crc32)) { + fprintf(stderr, "Invalid data crc32: 0x%08x instead of 0x%08x\n", crc32, le32_to_cpu(hdr.crc32)); + err = -EINVAL; + goto err_close; + } + + printf("Found a valid TRX version %d\n", le32_to_cpu(hdr.version)); + +err_close: + fclose(trx); +out: + return err; +} + +/************************************************** + * Create + **************************************************/ + +static ssize_t otrx_create_append_file(FILE *trx, const char *in_path) { + FILE *in; + size_t bytes; + ssize_t length = 0; + uint8_t buf[1024]; + + in = fopen(in_path, "r"); + if (!in) { + fprintf(stderr, "Couldn't open %s\n", in_path); + return -EACCES; + } + + while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) { + if (fwrite(buf, 1, bytes, trx) != bytes) { + fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, trx_path); + length = -EIO; + break; + } + length += bytes; + } + + fclose(in); + + return length; +} + +static ssize_t otrx_create_append_zeros(FILE *trx, size_t length) { + uint8_t *buf; + + buf = malloc(length); + if (!buf) + return -ENOMEM; + memset(buf, 0, length); + + if (fwrite(buf, 1, length, trx) != length) { + fprintf(stderr, "Couldn't write %zu B to %s\n", length, trx_path); + free(buf); + return -EIO; + } + + free(buf); + + return length; +} + +static ssize_t otrx_create_align(FILE *trx, size_t curr_offset, size_t alignment) { + if (curr_offset & (alignment - 1)) { + size_t length = alignment - (curr_offset % alignment); + return otrx_create_append_zeros(trx, length); + } + + return 0; +} + +static int otrx_create_write_hdr(FILE *trx, struct trx_header *hdr) { + size_t bytes, length; + uint8_t buf[1024]; + uint32_t crc32; + + hdr->magic = cpu_to_le32(TRX_MAGIC); + hdr->version = 1; + + fseek(trx, 0, SEEK_SET); + bytes = fwrite(hdr, 1, sizeof(struct trx_header), trx); + if (bytes != sizeof(struct trx_header)) { + fprintf(stderr, "Couldn't write TRX header to %s\n", trx_path); + return -EIO; + } + + length = le32_to_cpu(hdr->length); + + crc32 = 0xffffffff; + fseek(trx, TRX_FLAGS_OFFSET, SEEK_SET); + length -= TRX_FLAGS_OFFSET; + while ((bytes = fread(buf, 1, otrx_min(sizeof(buf), length), trx)) > 0) { + crc32 = otrx_crc32(crc32, buf, bytes); + length -= bytes; + } + hdr->crc32 = cpu_to_le32(crc32); + + fseek(trx, 0, SEEK_SET); + bytes = fwrite(hdr, 1, sizeof(struct trx_header), trx); + if (bytes != sizeof(struct trx_header)) { + fprintf(stderr, "Couldn't write TRX header to %s\n", trx_path); + return -EIO; + } + + return 0; +} + +static int otrx_create(int argc, char **argv) { + FILE *trx; + struct trx_header hdr = {}; + ssize_t sbytes; + size_t curr_idx = 0; + size_t curr_offset = sizeof(hdr); + int c; + int err = 0; + + if (argc < 3) { + fprintf(stderr, "No TRX file passed\n"); + err = -EINVAL; + goto out; + } + trx_path = argv[2]; + + trx = fopen(trx_path, "w+"); + if (!trx) { + fprintf(stderr, "Couldn't open %s\n", trx_path); + err = -EACCES; + goto out; + } + fseek(trx, curr_offset, SEEK_SET); + + optind = 3; + while ((c = getopt(argc, argv, "f:A:a:b:")) != -1) { + switch (c) { + case 'f': + if (curr_idx >= TRX_MAX_PARTS) { + err = -ENOSPC; + fprintf(stderr, "Reached TRX partitions limit, no place for %s\n", optarg); + goto err_close; + } + + sbytes = otrx_create_append_file(trx, optarg); + if (sbytes < 0) { + fprintf(stderr, "Failed to append file %s\n", optarg); + } else { + hdr.offset[curr_idx++] = curr_offset; + curr_offset += sbytes; + } + + sbytes = otrx_create_align(trx, curr_offset, 4); + if (sbytes < 0) + fprintf(stderr, "Failed to append zeros\n"); + else + curr_offset += sbytes; + + break; + case 'A': + sbytes = otrx_create_append_file(trx, optarg); + if (sbytes < 0) { + fprintf(stderr, "Failed to append file %s\n", optarg); + } else { + curr_offset += sbytes; + } + + sbytes = otrx_create_align(trx, curr_offset, 4); + if (sbytes < 0) + fprintf(stderr, "Failed to append zeros\n"); + else + curr_offset += sbytes; + break; + case 'a': + sbytes = otrx_create_align(trx, curr_offset, strtol(optarg, NULL, 0)); + if (sbytes < 0) + fprintf(stderr, "Failed to append zeros\n"); + else + curr_offset += sbytes; + break; + case 'b': + sbytes = strtol(optarg, NULL, 0) - curr_offset; + if (sbytes < 0) { + fprintf(stderr, "Current TRX length is 0x%zx, can't pad it with zeros to 0x%lx\n", curr_offset, strtol(optarg, NULL, 0)); + } else { + sbytes = otrx_create_append_zeros(trx, sbytes); + if (sbytes < 0) + fprintf(stderr, "Failed to append zeros\n"); + else + curr_offset += sbytes; + } + break; + } + if (err) + break; + } + + sbytes = otrx_create_align(trx, curr_offset, 0x1000); + if (sbytes < 0) + fprintf(stderr, "Failed to append zeros\n"); + else + curr_offset += sbytes; + + hdr.length = curr_offset; + otrx_create_write_hdr(trx, &hdr); +err_close: + fclose(trx); +out: + return err; +} + +/************************************************** + * Extract + **************************************************/ + +static void otrx_extract_parse_options(int argc, char **argv) { + int c; + + while ((c = getopt(argc, argv, "c:e:o:1:2:3:")) != -1) { + switch (c) { + case 'o': + trx_offset = atoi(optarg); + break; + case '1': + partition[0] = optarg; + break; + case '2': + partition[1] = optarg; + break; + case '3': + partition[2] = optarg; + break; + } + } +} + +static int otrx_extract_copy(FILE *trx, size_t offset, size_t length, char *out_path) { + FILE *out; + size_t bytes; + uint8_t *buf; + int err = 0; + + out = fopen(out_path, "w"); + if (!out) { + fprintf(stderr, "Couldn't open %s\n", out_path); + err = -EACCES; + goto out; + } + + buf = malloc(length); + if (!buf) { + fprintf(stderr, "Couldn't alloc %zu B buffer\n", length); + err = -ENOMEM; + goto err_close; + } + + fseek(trx, offset, SEEK_SET); + bytes = fread(buf, 1, length, trx); + if (bytes != length) { + fprintf(stderr, "Couldn't read %zu B of data from %s\n", length, trx_path); + err = -ENOMEM; + goto err_free_buf; + }; + + bytes = fwrite(buf, 1, length, out); + if (bytes != length) { + fprintf(stderr, "Couldn't write %zu B to %s\n", length, out_path); + err = -ENOMEM; + goto err_free_buf; + } + + printf("Extracted 0x%zx bytes into %s\n", length, out_path); + +err_free_buf: + free(buf); +err_close: + fclose(out); +out: + return err; +} + +static int otrx_extract(int argc, char **argv) { + FILE *trx; + struct trx_header hdr; + size_t bytes; + int i; + int err = 0; + + if (argc < 3) { + fprintf(stderr, "No TRX file passed\n"); + err = -EINVAL; + goto out; + } + trx_path = argv[2]; + + optind = 3; + otrx_extract_parse_options(argc, argv); + + trx = fopen(trx_path, "r"); + if (!trx) { + fprintf(stderr, "Couldn't open %s\n", trx_path); + err = -EACCES; + goto out; + } + + fseek(trx, trx_offset, SEEK_SET); + bytes = fread(&hdr, 1, sizeof(hdr), trx); + if (bytes != sizeof(hdr)) { + fprintf(stderr, "Couldn't read %s header\n", trx_path); + err = -EIO; + goto err_close; + } + + if (le32_to_cpu(hdr.magic) != TRX_MAGIC) { + fprintf(stderr, "Invalid TRX magic: 0x%08x\n", le32_to_cpu(hdr.magic)); + err = -EINVAL; + goto err_close; + } + + for (i = 0; i < TRX_MAX_PARTS; i++) { + size_t length; + + if (!partition[i]) + continue; + if (!hdr.offset[i]) { + printf("TRX doesn't contain partition %d, can't extract %s\n", i + 1, partition[i]); + continue; + } + + if (i + 1 >= TRX_MAX_PARTS || !hdr.offset[i + 1]) + length = le32_to_cpu(hdr.length) - le32_to_cpu(hdr.offset[i]); + else + length = le32_to_cpu(hdr.offset[i + 1]) - le32_to_cpu(hdr.offset[i]); + + otrx_extract_copy(trx, trx_offset + le32_to_cpu(hdr.offset[i]), length, partition[i]); + } + +err_close: + fclose(trx); +out: + return err; +} + +/************************************************** + * Start + **************************************************/ + +static void usage() { + printf("Usage:\n"); + printf("\n"); + printf("Checking TRX file:\n"); + printf("\totrx check <file> [options]\tcheck if file is a valid TRX\n"); + printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n"); + printf("\n"); + printf("Creating new TRX file:\n"); + printf("\totrx create <file> [options] [partitions]\n"); + printf("\t-f file\t\t\t\t[partition] start new partition with content copied from file\n"); + printf("\t-A file\t\t\t\t[partition] append current partition with content copied from file\n"); + printf("\t-a alignment\t\t\t[partition] align current partition\n"); + printf("\t-b offset\t\t\t[partition] append zeros to partition till reaching absolute offset\n"); + printf("\n"); + printf("Extracting from TRX file:\n"); + printf("\totrx extract <file> [options]\textract partitions from TRX file\n"); + printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n"); + printf("\t-1 file\t\t\t\tfile to extract 1st partition to (optional)\n"); + printf("\t-2 file\t\t\t\tfile to extract 2nd partition to (optional)\n"); + printf("\t-3 file\t\t\t\tfile to extract 3rd partition to (optional)\n"); +} + +int main(int argc, char **argv) { + if (argc > 1) { + if (!strcmp(argv[1], "check")) + return otrx_check(argc, argv); + else if (!strcmp(argv[1], "create")) + return otrx_create(argc, argv); + else if (!strcmp(argv[1], "extract")) + return otrx_extract(argc, argv); + } + + usage(); + return 0; +} diff --git a/tools/firmware-utils/src/pc1crypt.c b/tools/firmware-utils/src/pc1crypt.c index 9c2eb83f666..fe41b3dab5c 100644 --- a/tools/firmware-utils/src/pc1crypt.c +++ b/tools/firmware-utils/src/pc1crypt.c @@ -208,7 +208,7 @@ static int decrypt; #define ERRS(fmt, ...) do { \ int save = errno; \ fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ + fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ progname, ## __VA_ARGS__, strerror(save)); \ } while (0) diff --git a/tools/firmware-utils/src/ptgen.c b/tools/firmware-utils/src/ptgen.c index d94aabb5fcf..13e0eda6222 100644 --- a/tools/firmware-utils/src/ptgen.c +++ b/tools/firmware-utils/src/ptgen.c @@ -1,6 +1,6 @@ -/* +/* * ptgen - partition table generator - * Copyright (C) 2006 by Felix Fietkau <nbd@openwrt.org> + * Copyright (C) 2006 by Felix Fietkau <nbd@nbd.name> * * uses parts of afdisk * Copyright (C) 2002 by David Roetzel <david@roetzel.de> @@ -9,12 +9,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -26,25 +26,27 @@ #include <unistd.h> #include <stdlib.h> #include <stdio.h> +#include <stdint.h> #include <ctype.h> #include <fcntl.h> +#include <stdint.h> #if __BYTE_ORDER == __BIG_ENDIAN -#define cpu_to_le16(x) bswap_16(x) +#define cpu_to_le32(x) bswap_32(x) #elif __BYTE_ORDER == __LITTLE_ENDIAN -#define cpu_to_le16(x) (x) +#define cpu_to_le32(x) (x) #else #error unknown endianness! #endif /* Partition table entry */ -struct pte { - unsigned char active; - unsigned char chs_start[3]; - unsigned char type; - unsigned char chs_end[3]; - unsigned int start; - unsigned int length; +struct pte { + uint8_t active; + uint8_t chs_start[3]; + uint8_t type; + uint8_t chs_end[3]; + uint32_t start; + uint32_t length; }; struct partinfo { @@ -56,29 +58,31 @@ int verbose = 0; int active = 1; int heads = -1; int sectors = -1; +int kb_align = 0; struct partinfo parts[4]; char *filename = NULL; -/* +/* * parse the size argument, which is either * a simple number (K assumed) or * K, M or G * * returns the size in KByte */ -static long to_kbytes(const char *string) { +static long to_kbytes(const char *string) +{ int exp = 0; long result; char *end; result = strtoul(string, &end, 0); switch (tolower(*end)) { - case 'k' : - case '\0' : exp = 0; break; - case 'm' : exp = 1; break; - case 'g' : exp = 2; break; - default: return 0; + case 'k' : + case '\0' : exp = 0; break; + case 'm' : exp = 1; break; + case 'g' : exp = 2; break; + default: return 0; } if (*end) @@ -90,13 +94,16 @@ static long to_kbytes(const char *string) { } /* result: number + 1024^(exp) */ - return result * ((2 << ((10 * exp) - 1)) ?: 1); + if (exp == 0) + return result; + return result * (2 << ((10 * exp) - 1)); } /* convert the sector number into a CHS value for the partition table */ -static void to_chs(long sect, unsigned char chs[3]) { +static void to_chs(long sect, unsigned char chs[3]) +{ int c,h,s; - + s = (sect % sectors) + 1; sect = sect / sectors; h = sect % heads; @@ -111,17 +118,23 @@ static void to_chs(long sect, unsigned char chs[3]) { } /* round the sector number up to the next cylinder */ -static inline unsigned long round_to_cyl(long sect) { +static inline unsigned long round_to_cyl(long sect) +{ int cyl_size = heads * sectors; - return sect + cyl_size - (sect % cyl_size); + return sect + cyl_size - (sect % cyl_size); +} + +/* round the sector number up to the kb_align boundary */ +static inline unsigned long round_to_kb(long sect) { + return ((sect - 1) / kb_align + 1) * kb_align; } /* check the partition sizes and write the partition table */ -static int gen_ptable(int nr) +static int gen_ptable(uint32_t signature, int nr) { struct pte pte[4]; - unsigned long sect = 0; + unsigned long sect = 0; int i, fd, ret = -1, start, len; memset(pte, 0, sizeof(struct pte) * 4); @@ -130,17 +143,27 @@ static int gen_ptable(int nr) fprintf(stderr, "Invalid size in partition %d!\n", i); return -1; } + pte[i].active = ((i + 1) == active) ? 0x80 : 0; pte[i].type = parts[i].type; - pte[i].start = cpu_to_le16(start = sect + sectors); - sect = round_to_cyl(start + parts[i].size * 2); - pte[i].length = cpu_to_le16(len = sect - start); + + start = sect + sectors; + if (kb_align != 0) + start = round_to_kb(start); + pte[i].start = cpu_to_le32(start); + + sect = start + parts[i].size * 2; + if (kb_align == 0) + sect = round_to_cyl(sect); + pte[i].length = cpu_to_le32(len = sect - start); + to_chs(start, pte[i].chs_start); to_chs(start + len - 1, pte[i].chs_end); + if (verbose) - fprintf(stderr, "Partition %d: start=%ld, end=%ld, size=%ld\n", i, (long) start * 512, ((long) start + (long) len) * 512, (long) len * 512); - printf("%ld\n", ((long) start * 512)); - printf("%ld\n", ((long) len * 512)); + fprintf(stderr, "Partition %d: start=%ld, end=%ld, size=%ld\n", i, (long)start * 512, ((long)start + (long)len) * 512, (long)len * 512); + printf("%ld\n", (long)start * 512); + printf("%ld\n", (long)len * 512); } if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { @@ -148,6 +171,12 @@ static int gen_ptable(int nr) return -1; } + lseek(fd, 440, SEEK_SET); + if (write(fd, &signature, sizeof(signature)) != sizeof(signature)) { + fprintf(stderr, "write failed.\n"); + goto fail; + } + lseek(fd, 446, SEEK_SET); if (write(fd, pte, sizeof(struct pte) * 4) != sizeof(struct pte) * 4) { fprintf(stderr, "write failed.\n"); @@ -158,7 +187,7 @@ static int gen_ptable(int nr) fprintf(stderr, "write failed.\n"); goto fail; } - + ret = 0; fail: close(fd); @@ -167,8 +196,8 @@ fail: static void usage(char *prog) { - fprintf(stderr, "Usage: %s [-v] -h <heads> -s <sectors> -o <outputfile> [-a 0..4] [[-t <type>] -p <size>...] \n", prog); - exit(1); + fprintf(stderr, "Usage: %s [-v] -h <heads> -s <sectors> -o <outputfile> [-a 0..4] [-l <align kB>] [[-t <type>] -p <size>...] \n", prog); + exit(EXIT_FAILURE); } int main (int argc, char **argv) @@ -176,8 +205,9 @@ int main (int argc, char **argv) char type = 0x83; int ch; int part = 0; + uint32_t signature = 0x5452574F; /* 'OWRT' */ - while ((ch = getopt(argc, argv, "h:s:p:a:t:o:v")) != -1) { + while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vl:S:")) != -1) { switch (ch) { case 'o': filename = optarg; @@ -186,35 +216,41 @@ int main (int argc, char **argv) verbose++; break; case 'h': - heads = (int) strtoul(optarg, NULL, 0); + heads = (int)strtoul(optarg, NULL, 0); break; case 's': - sectors = (int) strtoul(optarg, NULL, 0); + sectors = (int)strtoul(optarg, NULL, 0); break; case 'p': if (part > 3) { fprintf(stderr, "Too many partitions\n"); - exit(1); + exit(EXIT_FAILURE); } parts[part].size = to_kbytes(optarg); parts[part++].type = type; break; case 't': - type = (char) strtoul(optarg, NULL, 16); + type = (char)strtoul(optarg, NULL, 16); break; case 'a': - active = (int) strtoul(optarg, NULL, 0); + active = (int)strtoul(optarg, NULL, 0); if ((active < 0) || (active > 4)) active = 0; break; + case 'l': + kb_align = (int)strtoul(optarg, NULL, 0) * 2; + break; + case 'S': + signature = strtoul(optarg, NULL, 0); + break; case '?': default: usage(argv[0]); } } argc -= optind; - if (argc || (heads <= 0) || (sectors <= 0) || !filename) + if (argc || (heads <= 0) || (sectors <= 0) || !filename) usage(argv[0]); - - return gen_ptable(part); + + return gen_ptable(signature, part) ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/tools/firmware-utils/src/seama.c b/tools/firmware-utils/src/seama.c new file mode 100644 index 00000000000..05aee8e76aa --- /dev/null +++ b/tools/firmware-utils/src/seama.c @@ -0,0 +1,529 @@ +/* vi: set sw=4 ts=4: */ +/* + * Copyright (C) 2008, Alpha Networks, Inc. + * Created by David Hsieh <david_hsieh@alphanetworks.com> + * All right reserved. + * + * (SEA)ttle i(MA)ge is the image which used in project seattle. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdarg.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> +#include <arpa/inet.h> + +#include "md5.h" +#include "seama.h" + +#define PROGNAME "seama" +#define VERSION "0.20" +#define MAX_SEAMA_META_SIZE 1024 +#define MAX_META 128 +#define MAX_IMAGE 128 + +extern int optind; +extern char * optarg; + +static int o_verbose = 0; /* verbose mode. */ +static char * o_dump = NULL; /* Seama file to dump. */ +static char * o_seal = NULL; /* Seal the input images when file name exist. */ +static char * o_extract = NULL; /* Extract the seama file. */ +static char * o_images[MAX_IMAGE];/* The image files to pack or seal */ +static int o_isize = 0; /* number of images */ +static char * o_meta[MAX_META]; /* meta data array */ +static int o_msize = 0; /* size of meta array */ + +static void verbose(const char * format, ...) +{ + va_list marker; + if (o_verbose) + { + va_start(marker, format); + vfprintf(stdout, format, marker); + va_end(marker); + } +} + +static void cleanup_exit(int exit_code) +{ + verbose("%s: exit with code %d\n", PROGNAME, exit_code); + exit(exit_code); +} + +static void show_usage(int exit_code) +{ + printf( PROGNAME " version " VERSION "\n" + "usage: " PROGNAME " [OPTIONS]\n" + " -h show this help message.\n" + " -v verbose mode.\n" + " -m {META data} META data.\n" + " -d {file} dump the info of the seama file.\n" + " -i {input file} image file name.\n" + " -s {file} Seal the images to the seama file.\n" + " -x {seama file} Extract the seama file.\n" + "\n" + " SEAMA can pack the input file (with -i) into a seama file.\n" + " ex: seama -i target.file\n" + " SEAMA can also seal multiple seama files into a single seama file.\n" + " ex: seama -s final.file -i taget1.seama -i target2.seama\n" + " To extract the raw image from SEAMA, you need to specify the meta.\n" + " The first image match the specified meta will be extract to\n" + " the output file which was specified with '-x'.\n" + " ex: seama -x output -i seama.image -m file=sealpac\n" + ); + cleanup_exit(exit_code); +} + +static int parse_args(int argc, char * argv[]) +{ + int opt; + + while ((opt = getopt(argc, argv, "hvd:s:i:m:x:")) > 0) + { + switch (opt) + { + default: show_usage(-1); break; + case 'h': show_usage(0); break; + case 'v': o_verbose++; break; + case 'd': o_dump = optarg; break; + case 's': o_seal = optarg; break; + case 'x': o_extract = optarg; break; + case 'i': + if (o_isize < MAX_IMAGE) o_images[o_isize++] = optarg; + else printf("Exceed the maximum acceptable image files.!\n"); + break; + case 'm': + if (o_msize < MAX_META) o_meta[o_msize++] = optarg; + else printf("Exceed the maximum acceptable META data.!\n"); + break; + } + } + return 0; +} + +/*******************************************************************/ + +static size_t calculate_digest(FILE * fh, size_t size, uint8_t * digest) +{ + MD5_CTX ctx; + size_t bytes_left, bytes_read, i; + uint8_t buf[MAX_SEAMA_META_SIZE]; + + bytes_left = size ? size : sizeof(buf); + bytes_read = 0; + + MD5_Init(&ctx); + while (!feof(fh) && !ferror(fh) && bytes_left > 0) + { + i = bytes_left < sizeof(buf) ? bytes_left : sizeof(buf); + i = fread(buf, sizeof(char), i, fh); + if (i > 0) + { + MD5_Update(&ctx, buf, i); + bytes_read += i; + } + if (size) bytes_left -= i; + } + MD5_Final(digest, &ctx); + return bytes_read; +} + +#define READ_BUFF_SIZE 8*1024 +static size_t copy_file(FILE * to, FILE * from) +{ + size_t i, fsize = 0; + uint8_t buf[READ_BUFF_SIZE]; + + while (!feof(from) && !ferror(from)) + { + i = fread(buf, sizeof(uint8_t), READ_BUFF_SIZE, from); + if (i > 0) + { + fsize += i; + fwrite(buf, sizeof(uint8_t), i, to); + } + } + return fsize; +} + +static int verify_seama(const char * fname, int msg) +{ + FILE * fh = NULL; + struct stat st; + seamahdr_t shdr; + uint8_t checksum[16]; + uint8_t digest[16]; + uint8_t buf[MAX_SEAMA_META_SIZE]; + size_t msize, isize, i; + int ret = -1; + +#define ERRBREAK(fmt, args...) { if (msg) printf(fmt, ##args); break; } + + do + { + if (stat(fname, &st) < 0) ERRBREAK("Unable to get the info of '%s'\n",fname); + if ((fh = fopen(fname, "r+"))==NULL) ERRBREAK("Unable to open '%s' for reading!\n",fname); + + /* Dump SEAMA header */ + if (msg) printf("FILE - %s (%d bytes)\n", fname, (int)st.st_size); + + /* SEAMA */ + while (!feof(fh) && !ferror(fh)) + { + /* read header */ + if (fread(&shdr, sizeof(shdr), 1, fh) != 1) break; + + /* Check the magic number */ + if (shdr.magic != htonl(SEAMA_MAGIC)) ERRBREAK("Invalid SEAMA magic. Probably no more SEAMA!\n"); + + /* Get the size */ + isize = ntohl(shdr.size); + msize = ntohs(shdr.metasize); + + /* The checksum exist only if size is greater than zero. */ + if (isize > 0) + { + if (fread(checksum, sizeof(checksum), 1, fh) != 1) + ERRBREAK("Error reading checksum !\n"); + } + + /* Check the META size. */ + if (msize > sizeof(buf)) ERRBREAK("META data in SEAMA header is too large!\n"); + + /* Read META data. */ + if (fread(buf, sizeof(char), msize, fh) != msize) + ERRBREAK("Unable to read SEAMA META data!\n"); + + /* dump header */ + if (msg) + { + printf("SEAMA ==========================================\n"); + printf(" magic : %08x\n", ntohl(shdr.magic)); + printf(" meta size : %zu bytes\n", msize); + for (i=0; i<msize; i+=(strlen((const char *)&buf[i])+1)) + printf(" meta data : %s\n", &buf[i]); + printf(" image size : %zu bytes\n", isize); + } + + /* verify checksum */ + if (isize > 0) + { + if (msg) + { + printf(" checksum : "); + for (i=0; i<16; i++) printf("%02X", checksum[i]); + printf("\n"); + } + + /* Calculate the checksum */ + calculate_digest(fh, isize, digest); + if (msg) + { + printf(" digest : "); + for (i=0; i<16; i++) printf("%02X", digest[i]); + printf("\n"); + } + + if (memcmp(checksum, digest, 16)!=0) ERRBREAK("!!ERROR!! checksum error !!\n"); + ret = 0; + } + } + if (msg) printf("================================================\n"); + } while (0); + if (fh) fclose(fh); + return ret; +} + +static size_t write_seama_header(FILE * fh, char * meta[], size_t msize, size_t size) +{ + seamahdr_t shdr; + size_t i; + uint16_t metasize = 0; + + /* Calculate the META size */ + for (i=0; i<msize; i++) metasize += (strlen(meta[i]) + 1); + //+++ let meta data end on 4 alignment by siyou. 2010/3/1 03:58pm + metasize = ((metasize+3)/4)*4; + verbose("SEAMA META : %d bytes\n", metasize); + + /* Fill up the header, all the data endian should be network byte order. */ + shdr.magic = htonl(SEAMA_MAGIC); + shdr.reserved = 0; + shdr.metasize = htons(metasize); + shdr.size = htonl(size); + + /* Write the header */ + return fwrite(&shdr, sizeof(seamahdr_t), 1, fh); +} + +static size_t write_checksum(FILE * fh, uint8_t * checksum) +{ + return fwrite(checksum, sizeof(uint8_t), 16, fh); +} + +static size_t write_meta_data(FILE * fh, char * meta[], size_t size) +{ + size_t i,j; + size_t ret = 0; + + for (i=0; i<size; i++) + { + verbose("SEAMA META data : %s\n", meta[i]); + j = fwrite(meta[i], sizeof(char), strlen(meta[i])+1, fh); + if (j != strlen(meta[i])+1) return 0; + ret += j; + } + //+++ let meta data end on 4 alignment by siyou. 2010/3/1 03:58pm + j = ((ret+3)/4)*4; + for ( ; ret < j; ret++) + fwrite("", sizeof(char), 1, fh); + + return ret; +} + +/*******************************************************************/ + +static void dump_seama(const char * fname) +{ + verify_seama(fname, 1); +} + +static void seal_files(const char * file) +{ + FILE * fh; + FILE * ifh; + size_t i; + + /* Each image should be seama. */ + for (i = 0; i < o_isize; i++) + { + if (verify_seama(o_images[i], 0) < 0) + { + printf("'%s' is not a seama file !\n",o_images[i]); + return; + } + } + + /* Open file for write */ + fh = fopen(file, "w+"); + if (fh) + { + /* Write the header. */ + write_seama_header(fh, o_meta, o_msize, 0); + write_meta_data(fh, o_meta, o_msize); + + /* Write image files */ + for (i=0; i<o_isize; i++) + { + ifh = fopen(o_images[i], "r+"); + if (ifh) + { + copy_file(fh, ifh); + fclose(ifh); + } + } + + fclose(fh); + } +} + +static void pack_files(void) +{ + FILE * fh; + FILE * ifh; + size_t i, fsize; + char filename[512]; + uint8_t digest[16]; + + for (i=0; i<o_isize; i++) + { + /* Open the input file. */ + ifh = fopen(o_images[i], "r+"); + if (ifh) + { + fsize = calculate_digest(ifh, 0, digest); + verbose("file size (%s) : %d\n", o_images[i], fsize); + rewind(ifh); + + /* Open the output file. */ + sprintf(filename, "%s.seama", o_images[i]); + fh = fopen(filename, "w+"); + if (fh) + { + write_seama_header(fh, o_meta, o_msize, fsize); + write_checksum(fh, digest); + write_meta_data(fh, o_meta, o_msize); + copy_file(fh, ifh); + fclose(fh); + } + fclose(ifh); + } + else + { + printf("Unable to open image file '%s'\n",o_images[i]); + } + } +} + +/**************************************************************************/ + +static int match_meta(const char * meta, size_t size) +{ + size_t i, j; + int match; + + for (i = 0; i < o_msize; i++) + { + for (match = 0, j = 0; j < size; j += (strlen(&meta[j])+1)) + if (strcmp(&meta[j], o_meta[i])==0) { match++; break; } + if (!match) return 0; + } + return 1; +} + + +static void extract_file(const char * output) +{ + FILE * ifh = NULL; + FILE * ofh = NULL; + size_t msize, isize, i, m; + seamahdr_t shdr; + uint8_t buf[MAX_SEAMA_META_SIZE]; + int done = 0; + + /* We need meta for searching the target image. */ + if (o_msize == 0) + { + printf("SEAMA: need meta for searching image.\n"); + return; + } + + /* Walk through each input file */ + for (i = 0; i < o_isize; i++) + { + /* verify the input file */ + if (verify_seama(o_images[i], 0) < 0) + { + printf("SEAMA: '%s' is not a seama file !\n", o_images[i]); + continue; + } + /* open the input file */ + ifh = fopen(o_images[i], "r"); + if (!ifh) continue; + /* read file */ + while (!feof(ifh) && !ferror(ifh)) + { + /* read header */ + fread(&shdr, sizeof(shdr), 1, ifh); + if (shdr.magic != htonl(SEAMA_MAGIC)) break; + /* Get the size */ + isize = ntohl(shdr.size); + msize = ntohs(shdr.metasize); + if (isize == 0) + { + while (msize > 0) + { + m = fread(buf, sizeof(char), (msize < MAX_SEAMA_META_SIZE) ? msize : MAX_SEAMA_META_SIZE, ifh); + if (m <= 0) break; + msize -= m; + } + continue; + } + /* read checksum */ + fread(buf, sizeof(char), 16, ifh); + if (msize > 0) + { + /* read META */ + fread(buf, sizeof(char), msize, ifh); + if (match_meta((const char *)buf, msize)) + { + printf("SEAMA: found image @ '%s', image size: %zu\n", o_images[i], isize); + /* open output file */ + ofh = fopen(output, "w"); + if (!ofh) printf("SEAMA: unable to open '%s' for writting.\n",output); + else + { + while (isize > 0) + { + m = fread(buf, sizeof(char), (isize < MAX_SEAMA_META_SIZE) ? isize : MAX_SEAMA_META_SIZE, ifh); + if (m <= 0) break; + fwrite(buf, sizeof(char), m, ofh); + isize -= m; + } + fclose(ofh); + } + done++; + break; + } + } + while (isize > 0) + { + m = fread(buf, sizeof(char), (isize < MAX_SEAMA_META_SIZE) ? isize : MAX_SEAMA_META_SIZE, ifh); + if (m <= 0) break; + isize -= m; + } + } + /* close the file. */ + fclose(ifh); + if (done) break; + } + return; +} + +/*******************************************************************/ +#ifdef RGBIN_BOX +int seama_main(int argc, char * argv[], char * env[]) +#else +int main(int argc, char * argv[], char * env[]) +#endif +{ + verbose("SEAMA version " VERSION "\n"); + + /* parse the arguments */ + if (parse_args(argc, argv) < 0) show_usage(9); + + /* Do the works */ + if (o_dump) dump_seama(o_dump); + else if (o_seal) seal_files(o_seal); + else if (o_extract) extract_file(o_extract); + else pack_files(); + + cleanup_exit(0); + return 0; +} diff --git a/tools/firmware-utils/src/seama.h b/tools/firmware-utils/src/seama.h new file mode 100644 index 00000000000..02683b6e98d --- /dev/null +++ b/tools/firmware-utils/src/seama.h @@ -0,0 +1,108 @@ +/* vi: set sw=4 ts=4: */ +/* + * (SEA)ttle i(MA)ge is the image which used in project seattle. + * + * Created by David Hsieh <david_hsieh@alphanetworks.com> + * Copyright (C) 2008-2009 Alpha Networks, Inc. + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either' + * version 2.1 of the License, or (at your option) any later version. + * + * The GNU C Library is distributed in the hope that it will be useful,' + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the GNU C Library; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA. + */ + +#ifndef __SEAMA_HEADER_FILE__ +#define __SEAMA_HEADER_FILE__ + +#include <stdint.h> + +#define SEAMA_MAGIC 0x5EA3A417 + +/* + * SEAMA looks like the following map. + * All the data of the header should be in network byte order. + * + * +-------------+-------------+------------ + * | SEAMA magic | ^ + * +-------------+-------------+ | + * | reserved | meta size | | + * +-------------+-------------+ header + * | image size (0 bytes) | | + * +-------------+-------------+ | + * ~ Meta data ~ v + * +-------------+-------------+------------ + * | SEAMA magic | ^ ^ + * +-------------+-------------+ | | + * | reserved | meta size | | | + * +-------------+-------------+ | | + * | image size | | | + * +-------------+-------------+ header | + * | | | | + * | 16 bytes of MD5 digest | | | + * | | | | + * | | | | + * +-------------+-------------+ | | + * ~ Meta data ~ v | + * +-------------+-------------+------- | + * | | | + * | Image of the 1st entity | | + * ~ ~ 1st entity + * | | | + * | | v + * +-------------+-------------+------------- + * | SEAMA magic | ^ ^ + * +-------------+-------------+ | | + * | reserved | meta size | | | + * +-------------+-------------+ | | + * | image size | | | + * +-------------+-------------+ header | + * | | | | + * | 16 bytes of MD5 digest | | | + * | | | | + * | | | | + * +-------------+-------------+ | | + * ~ Meta data ~ v | + * +-------------+-------------+------- | + * | | | + * | Image of the 2nd entity | | + * ~ ~ 2nd entity + * | | | + * | | v + * +-------------+-------------+------------- + */ + + +/* + * SEAMA header + * + * |<-------- 32 bits -------->| + * +-------------+-------------+ + * | SEAMA magic | + * +-------------+-------------+ + * | reserved | meta size | + * +-------------+-------------+ + * | image size | + * +-------------+-------------+ + */ +/* seama header */ +typedef struct seama_hdr seamahdr_t; +struct seama_hdr +{ + uint32_t magic; /* should always be SEAMA_MAGIC. */ + uint16_t reserved; /* reserved for */ + uint16_t metasize; /* size of the META data */ + uint32_t size; /* size of the image */ +} __attribute__ ((packed)); + + +#endif diff --git a/tools/firmware-utils/src/spw303v.c b/tools/firmware-utils/src/spw303v.c index ae34a1ebddc..684532d7e11 100644 --- a/tools/firmware-utils/src/spw303v.c +++ b/tools/firmware-utils/src/spw303v.c @@ -18,11 +18,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> -#include <time.h> #include <unistd.h> #include <sys/stat.h> diff --git a/tools/firmware-utils/src/srec2bin.c b/tools/firmware-utils/src/srec2bin.c index 1cffbaed969..5cc71bda220 100644 --- a/tools/firmware-utils/src/srec2bin.c +++ b/tools/firmware-utils/src/srec2bin.c @@ -513,7 +513,7 @@ int srec2bin(int argc,char *argv[],int verbose) return(1); } -main(int argc, char *argv[]) +int main(int argc, char *argv[]) { debug = TRUE; debug = FALSE; diff --git a/tools/firmware-utils/src/tplink-safeloader.c b/tools/firmware-utils/src/tplink-safeloader.c new file mode 100644 index 00000000000..78092bc535c --- /dev/null +++ b/tools/firmware-utils/src/tplink-safeloader.c @@ -0,0 +1,2084 @@ +/* + Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net> + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/* + tplink-safeloader + + Image generation tool for the TP-LINK SafeLoader as seen on + TP-LINK Pharos devices (CPE210/220/510/520) +*/ + + +#include <assert.h> +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include <arpa/inet.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <limits.h> + +#include "md5.h" + + +#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); }) + + +#define MAX_PARTITIONS 32 + +/** An image partition table entry */ +struct image_partition_entry { + const char *name; + size_t size; + uint8_t *data; +}; + +/** A flash partition table entry */ +struct flash_partition_entry { + char *name; + uint32_t base; + uint32_t size; +}; + +/** Firmware layout description */ +struct device_info { + const char *id; + const char *vendor; + const char *support_list; + char support_trail; + const char *soft_ver; + struct flash_partition_entry partitions[MAX_PARTITIONS+1]; + const char *first_sysupgrade_partition; + const char *last_sysupgrade_partition; +}; + +/** The content of the soft-version structure */ +struct __attribute__((__packed__)) soft_version { + uint32_t magic; + uint32_t zero; + uint8_t pad1; + uint8_t version_major; + uint8_t version_minor; + uint8_t version_patch; + uint8_t year_hi; + uint8_t year_lo; + uint8_t month; + uint8_t day; + uint32_t rev; + uint8_t pad2; +}; + + +static const uint8_t jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde}; + + +/** + Salt for the MD5 hash + + Fortunately, TP-LINK seems to use the same salt for most devices which use + the new image format. +*/ +static const uint8_t md5_salt[16] = { + 0x7a, 0x2b, 0x15, 0xed, + 0x9b, 0x98, 0x59, 0x6d, + 0xe5, 0x04, 0xab, 0x44, + 0xac, 0x2a, 0x9f, 0x4e, +}; + + +/** Firmware layout table */ +static struct device_info boards[] = { + /** Firmware layout for the CPE210/220 */ + { + .id = "CPE210", + .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", + .support_list = + "SupportList:\r\n" + "CPE210(TP-LINK|UN|N300-2):1.0\r\n" + "CPE210(TP-LINK|UN|N300-2):1.1\r\n" + "CPE210(TP-LINK|US|N300-2):1.1\r\n" + "CPE210(TP-LINK|EU|N300-2):1.1\r\n" + "CPE220(TP-LINK|UN|N300-2):1.1\r\n" + "CPE220(TP-LINK|US|N300-2):1.1\r\n" + "CPE220(TP-LINK|EU|N300-2):1.1\r\n", + .support_trail = '\xff', + .soft_ver = NULL, + + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"partition-table", 0x20000, 0x02000}, + {"default-mac", 0x30000, 0x00020}, + {"product-info", 0x31100, 0x00100}, + {"signature", 0x32000, 0x00400}, + {"os-image", 0x40000, 0x1c0000}, + {"file-system", 0x200000, 0x5b0000}, + {"soft-version", 0x7b0000, 0x00100}, + {"support-list", 0x7b1000, 0x00400}, + {"user-config", 0x7c0000, 0x10000}, + {"default-config", 0x7d0000, 0x10000}, + {"log", 0x7e0000, 0x10000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "support-list", + }, + + /** Firmware layout for the CPE210 V2 */ + { + .id = "CPE210V2", + .vendor = "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n", + .support_list = + "SupportList:\r\n" + "CPE210(TP-LINK|EU|N300-2|00000000):2.0\r\n" + "CPE210(TP-LINK|EU|N300-2|45550000):2.0\r\n" + "CPE210(TP-LINK|EU|N300-2|55530000):2.0\r\n" + "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n" + "CPE210(TP-LINK|UN|N300-2|45550000):2.0\r\n" + "CPE210(TP-LINK|UN|N300-2|55530000):2.0\r\n" + "CPE210(TP-LINK|US|N300-2|55530000):2.0\r\n" + "CPE210(TP-LINK|UN|N300-2):2.0\r\n" + "CPE210(TP-LINK|EU|N300-2):2.0\r\n" + "CPE210(TP-LINK|US|N300-2):2.0\r\n", + .support_trail = '\xff', + .soft_ver = NULL, + + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"partition-table", 0x20000, 0x02000}, + {"default-mac", 0x30000, 0x00020}, + {"product-info", 0x31100, 0x00100}, + {"device-info", 0x31400, 0x00400}, + {"signature", 0x32000, 0x00400}, + {"device-id", 0x33000, 0x00100}, + {"os-image", 0x40000, 0x1c0000}, + {"file-system", 0x200000, 0x5b0000}, + {"soft-version", 0x7b0000, 0x00100}, + {"support-list", 0x7b1000, 0x01000}, + {"user-config", 0x7c0000, 0x10000}, + {"default-config", 0x7d0000, 0x10000}, + {"log", 0x7e0000, 0x10000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "support-list", + }, + + /** Firmware layout for the CPE510/520 */ + { + .id = "CPE510", + .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", + .support_list = + "SupportList:\r\n" + "CPE510(TP-LINK|UN|N300-5):1.0\r\n" + "CPE510(TP-LINK|UN|N300-5):1.1\r\n" + "CPE510(TP-LINK|UN|N300-5):1.1\r\n" + "CPE510(TP-LINK|US|N300-5):1.1\r\n" + "CPE510(TP-LINK|EU|N300-5):1.1\r\n" + "CPE520(TP-LINK|UN|N300-5):1.1\r\n" + "CPE520(TP-LINK|US|N300-5):1.1\r\n" + "CPE520(TP-LINK|EU|N300-5):1.1\r\n" + "CPE510(TP-LINK|EU|N300-5|00000000):2.0\r\n" + "CPE510(TP-LINK|EU|N300-5|45550000):2.0\r\n" + "CPE510(TP-LINK|EU|N300-5|55530000):2.0\r\n" + "CPE510(TP-LINK|UN|N300-5|00000000):2.0\r\n" + "CPE510(TP-LINK|UN|N300-5|45550000):2.0\r\n" + "CPE510(TP-LINK|UN|N300-5|55530000):2.0\r\n" + "CPE510(TP-LINK|US|N300-5|55530000):2.0\r\n" + "CPE510(TP-LINK|UN|N300-5):2.0\r\n" + "CPE510(TP-LINK|EU|N300-5):2.0\r\n" + "CPE510(TP-LINK|US|N300-5):2.0\r\n", + .support_trail = '\xff', + .soft_ver = NULL, + + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"partition-table", 0x20000, 0x02000}, + {"default-mac", 0x30000, 0x00020}, + {"product-info", 0x31100, 0x00100}, + {"signature", 0x32000, 0x00400}, + {"os-image", 0x40000, 0x1c0000}, + {"file-system", 0x200000, 0x5b0000}, + {"soft-version", 0x7b0000, 0x00100}, + {"support-list", 0x7b1000, 0x00400}, + {"user-config", 0x7c0000, 0x10000}, + {"default-config", 0x7d0000, 0x10000}, + {"log", 0x7e0000, 0x10000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "support-list", + }, + + { + .id = "WBS210", + .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", + .support_list = + "SupportList:\r\n" + "WBS210(TP-LINK|UN|N300-2):1.20\r\n" + "WBS210(TP-LINK|US|N300-2):1.20\r\n" + "WBS210(TP-LINK|EU|N300-2):1.20\r\n", + .support_trail = '\xff', + .soft_ver = NULL, + + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"partition-table", 0x20000, 0x02000}, + {"default-mac", 0x30000, 0x00020}, + {"product-info", 0x31100, 0x00100}, + {"signature", 0x32000, 0x00400}, + {"os-image", 0x40000, 0x1c0000}, + {"file-system", 0x200000, 0x5b0000}, + {"soft-version", 0x7b0000, 0x00100}, + {"support-list", 0x7b1000, 0x00400}, + {"user-config", 0x7c0000, 0x10000}, + {"default-config", 0x7d0000, 0x10000}, + {"log", 0x7e0000, 0x10000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "support-list", + }, + + { + .id = "WBS510", + .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", + .support_list = + "SupportList:\r\n" + "WBS510(TP-LINK|UN|N300-5):1.20\r\n" + "WBS510(TP-LINK|US|N300-5):1.20\r\n" + "WBS510(TP-LINK|EU|N300-5):1.20\r\n", + .support_trail = '\xff', + .soft_ver = NULL, + + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"partition-table", 0x20000, 0x02000}, + {"default-mac", 0x30000, 0x00020}, + {"product-info", 0x31100, 0x00100}, + {"signature", 0x32000, 0x00400}, + {"os-image", 0x40000, 0x1c0000}, + {"file-system", 0x200000, 0x5b0000}, + {"soft-version", 0x7b0000, 0x00100}, + {"support-list", 0x7b1000, 0x00400}, + {"user-config", 0x7c0000, 0x10000}, + {"default-config", 0x7d0000, 0x10000}, + {"log", 0x7e0000, 0x10000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "support-list", + }, + + /** Firmware layout for the C2600 */ + { + .id = "C2600", + .vendor = "", + .support_list = + "SupportList:\r\n" + "{product_name:Archer C2600,product_ver:1.0.0,special_id:00000000}\r\n", + .support_trail = '\x00', + .soft_ver = NULL, + + /** + We use a bigger os-image partition than the stock images (and thus + smaller file-system), as our kernel doesn't fit in the stock firmware's + 2 MB os-image since kernel 4.14. + */ + .partitions = { + {"SBL1", 0x00000, 0x20000}, + {"MIBIB", 0x20000, 0x20000}, + {"SBL2", 0x40000, 0x20000}, + {"SBL3", 0x60000, 0x30000}, + {"DDRCONFIG", 0x90000, 0x10000}, + {"SSD", 0xa0000, 0x10000}, + {"TZ", 0xb0000, 0x30000}, + {"RPM", 0xe0000, 0x20000}, + {"fs-uboot", 0x100000, 0x70000}, + {"uboot-env", 0x170000, 0x40000}, + {"radio", 0x1b0000, 0x40000}, + {"os-image", 0x1f0000, 0x400000}, /* Stock: base 0x1f0000 size 0x200000 */ + {"file-system", 0x5f0000, 0x1900000}, /* Stock: base 0x3f0000 size 0x1b00000 */ + {"default-mac", 0x1ef0000, 0x00200}, + {"pin", 0x1ef0200, 0x00200}, + {"product-info", 0x1ef0400, 0x0fc00}, + {"partition-table", 0x1f00000, 0x10000}, + {"soft-version", 0x1f10000, 0x10000}, + {"support-list", 0x1f20000, 0x10000}, + {"profile", 0x1f30000, 0x10000}, + {"default-config", 0x1f40000, 0x10000}, + {"user-config", 0x1f50000, 0x40000}, + {"qos-db", 0x1f90000, 0x40000}, + {"usb-config", 0x1fd0000, 0x10000}, + {"log", 0x1fe0000, 0x20000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + + /** Firmware layout for the C25v1 */ + { + .id = "ARCHER-C25-V1", + .support_list = + "SupportList:\n" + "{product_name:ArcherC25,product_ver:1.0.0,special_id:00000000}\n" + "{product_name:ArcherC25,product_ver:1.0.0,special_id:55530000}\n" + "{product_name:ArcherC25,product_ver:1.0.0,special_id:45550000}\n", + .support_trail = '\x00', + .soft_ver = "soft_ver:1.0.0\n", + + /** + We use a bigger os-image partition than the stock images (and thus + smaller file-system), as our kernel doesn't fit in the stock firmware's + 1MB os-image. + */ + .partitions = { + {"factory-boot", 0x00000, 0x20000}, + {"fs-uboot", 0x20000, 0x10000}, + {"os-image", 0x30000, 0x180000}, /* Stock: base 0x30000 size 0x100000 */ + {"file-system", 0x1b0000, 0x620000}, /* Stock: base 0x130000 size 0x6a0000 */ + {"user-config", 0x7d0000, 0x04000}, + {"default-mac", 0x7e0000, 0x00100}, + {"device-id", 0x7e0100, 0x00100}, + {"extra-para", 0x7e0200, 0x00100}, + {"pin", 0x7e0300, 0x00100}, + {"support-list", 0x7e0400, 0x00400}, + {"soft-version", 0x7e0800, 0x00400}, + {"product-info", 0x7e0c00, 0x01400}, + {"partition-table", 0x7e2000, 0x01000}, + {"profile", 0x7e3000, 0x01000}, + {"default-config", 0x7e4000, 0x04000}, + {"merge-config", 0x7ec000, 0x02000}, + {"qos-db", 0x7ee000, 0x02000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system", + }, + + /** Firmware layout for the C58v1 */ + { + .id = "ARCHER-C58-V1", + .vendor = "", + .support_list = + "SupportList:\r\n" + "{product_name:Archer C58,product_ver:1.0.0,special_id:00000000}\r\n" + "{product_name:Archer C58,product_ver:1.0.0,special_id:45550000}\r\n" + "{product_name:Archer C58,product_ver:1.0.0,special_id:55530000}\r\n", + .support_trail = '\x00', + .soft_ver = "soft_ver:1.0.0\n", + + .partitions = { + {"fs-uboot", 0x00000, 0x10000}, + {"default-mac", 0x10000, 0x00200}, + {"pin", 0x10200, 0x00200}, + {"product-info", 0x10400, 0x00100}, + {"partition-table", 0x10500, 0x00800}, + {"soft-version", 0x11300, 0x00200}, + {"support-list", 0x11500, 0x00100}, + {"device-id", 0x11600, 0x00100}, + {"profile", 0x11700, 0x03900}, + {"default-config", 0x15000, 0x04000}, + {"user-config", 0x19000, 0x04000}, + {"os-image", 0x20000, 0x180000}, + {"file-system", 0x1a0000, 0x648000}, + {"certyficate", 0x7e8000, 0x08000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system", + }, + + /** Firmware layout for the C59v1 */ + { + .id = "ARCHER-C59-V1", + .vendor = "", + .support_list = + "SupportList:\r\n" + "{product_name:Archer C59,product_ver:1.0.0,special_id:00000000}\r\n" + "{product_name:Archer C59,product_ver:1.0.0,special_id:45550000}\r\n" + "{product_name:Archer C59,product_ver:1.0.0,special_id:52550000}\r\n" + "{product_name:Archer C59,product_ver:1.0.0,special_id:55530000}\r\n", + .support_trail = '\x00', + .soft_ver = "soft_ver:1.0.0\n", + + .partitions = { + {"fs-uboot", 0x00000, 0x10000}, + {"default-mac", 0x10000, 0x00200}, + {"pin", 0x10200, 0x00200}, + {"device-id", 0x10400, 0x00100}, + {"product-info", 0x10500, 0x0fb00}, + {"os-image", 0x20000, 0x180000}, + {"file-system", 0x1a0000, 0xcb0000}, + {"partition-table", 0xe50000, 0x10000}, + {"soft-version", 0xe60000, 0x10000}, + {"support-list", 0xe70000, 0x10000}, + {"profile", 0xe80000, 0x10000}, + {"default-config", 0xe90000, 0x10000}, + {"user-config", 0xea0000, 0x40000}, + {"usb-config", 0xee0000, 0x10000}, + {"certificate", 0xef0000, 0x10000}, + {"qos-db", 0xf00000, 0x40000}, + {"log", 0xfe0000, 0x10000}, + {"radio", 0xff0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system", + }, + + /** Firmware layout for the C59v2 */ + { + .id = "ARCHER-C59-V2", + .vendor = "", + .support_list = + "SupportList:\r\n" + "{product_name:Archer C59,product_ver:2.0.0,special_id:00000000}\r\n" + "{product_name:Archer C59,product_ver:2.0.0,special_id:45550000}\r\n" + "{product_name:Archer C59,product_ver:2.0.0,special_id:55530000}\r\n", + .support_trail = '\x00', + .soft_ver = "soft_ver:2.0.0 Build 20161206 rel.7303\n", + + /** We're using a dynamic kernel/rootfs split here */ + .partitions = { + {"factory-boot", 0x00000, 0x20000}, + {"fs-uboot", 0x20000, 0x10000}, + {"default-mac", 0x30000, 0x00200}, + {"pin", 0x30200, 0x00200}, + {"device-id", 0x30400, 0x00100}, + {"product-info", 0x30500, 0x0fb00}, + {"firmware", 0x40000, 0xe10000}, + {"partition-table", 0xe50000, 0x10000}, + {"soft-version", 0xe60000, 0x10000}, + {"support-list", 0xe70000, 0x10000}, + {"profile", 0xe80000, 0x10000}, + {"default-config", 0xe90000, 0x10000}, + {"user-config", 0xea0000, 0x40000}, + {"usb-config", 0xee0000, 0x10000}, + {"certificate", 0xef0000, 0x10000}, + {"extra-para", 0xf00000, 0x10000}, + {"qos-db", 0xf10000, 0x30000}, + {"log", 0xfe0000, 0x10000}, + {"radio", 0xff0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system", + }, + + /** Firmware layout for the C60v1 */ + { + .id = "ARCHER-C60-V1", + .vendor = "", + .support_list = + "SupportList:\r\n" + "{product_name:Archer C60,product_ver:1.0.0,special_id:00000000}\r\n" + "{product_name:Archer C60,product_ver:1.0.0,special_id:45550000}\r\n" + "{product_name:Archer C60,product_ver:1.0.0,special_id:55530000}\r\n", + .support_trail = '\x00', + .soft_ver = "soft_ver:1.0.0\n", + + .partitions = { + {"fs-uboot", 0x00000, 0x10000}, + {"default-mac", 0x10000, 0x00200}, + {"pin", 0x10200, 0x00200}, + {"product-info", 0x10400, 0x00100}, + {"partition-table", 0x10500, 0x00800}, + {"soft-version", 0x11300, 0x00200}, + {"support-list", 0x11500, 0x00100}, + {"device-id", 0x11600, 0x00100}, + {"profile", 0x11700, 0x03900}, + {"default-config", 0x15000, 0x04000}, + {"user-config", 0x19000, 0x04000}, + {"os-image", 0x20000, 0x180000}, + {"file-system", 0x1a0000, 0x648000}, + {"certyficate", 0x7e8000, 0x08000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system", + }, + + /** Firmware layout for the C60v2 */ + { + .id = "ARCHER-C60-V2", + .vendor = "", + .support_list = + "SupportList:\r\n" + "{product_name:Archer C60,product_ver:2.0.0,special_id:42520000}\r\n" + "{product_name:Archer C60,product_ver:2.0.0,special_id:45550000}\r\n" + "{product_name:Archer C60,product_ver:2.0.0,special_id:55530000}\r\n", + .support_trail = '\x00', + .soft_ver = "soft_ver:2.0.0\n", + + .partitions = { + {"factory-boot", 0x00000, 0x1fb00}, + {"default-mac", 0x1fb00, 0x00200}, + {"pin", 0x1fd00, 0x00100}, + {"product-info", 0x1fe00, 0x00100}, + {"device-id", 0x1ff00, 0x00100}, + {"fs-uboot", 0x20000, 0x10000}, + {"os-image", 0x30000, 0x180000}, + {"file-system", 0x1b0000, 0x620000}, + {"soft-version", 0x7d9500, 0x00100}, + {"support-list", 0x7d9600, 0x00100}, + {"extra-para", 0x7d9700, 0x00100}, + {"profile", 0x7d9800, 0x03000}, + {"default-config", 0x7dc800, 0x03000}, + {"partition-table", 0x7df800, 0x00800}, + {"user-config", 0x7e0000, 0x0c000}, + {"certificate", 0x7ec000, 0x04000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system", + }, + + /** Firmware layout for the C5 */ + { + .id = "ARCHER-C5-V2", + .vendor = "", + .support_list = + "SupportList:\r\n" + "{product_name:ArcherC5,product_ver:2.0.0,special_id:00000000}\r\n" + "{product_name:ArcherC5,product_ver:2.0.0,special_id:55530000}\r\n" + "{product_name:ArcherC5,product_ver:2.0.0,special_id:4A500000}\r\n", /* JP version */ + .support_trail = '\x00', + .soft_ver = NULL, + + .partitions = { + {"fs-uboot", 0x00000, 0x40000}, + {"os-image", 0x40000, 0x200000}, + {"file-system", 0x240000, 0xc00000}, + {"default-mac", 0xe40000, 0x00200}, + {"pin", 0xe40200, 0x00200}, + {"product-info", 0xe40400, 0x00200}, + {"partition-table", 0xe50000, 0x10000}, + {"soft-version", 0xe60000, 0x00200}, + {"support-list", 0xe61000, 0x0f000}, + {"profile", 0xe70000, 0x10000}, + {"default-config", 0xe80000, 0x10000}, + {"user-config", 0xe90000, 0x50000}, + {"log", 0xee0000, 0x100000}, + {"radio_bk", 0xfe0000, 0x10000}, + {"radio", 0xff0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + + /** Firmware layout for the C7 */ + { + .id = "ARCHER-C7-V4", + .support_list = + "SupportList:\n" + "{product_name:Archer C7,product_ver:4.0.0,special_id:00000000}\n" + "{product_name:Archer C7,product_ver:4.0.0,special_id:41550000}\n" + "{product_name:Archer C7,product_ver:4.0.0,special_id:45550000}\n" + "{product_name:Archer C7,product_ver:4.0.0,special_id:4B520000}\n" + "{product_name:Archer C7,product_ver:4.0.0,special_id:42520000}\n" + "{product_name:Archer C7,product_ver:4.0.0,special_id:4A500000}\n" + "{product_name:Archer C7,product_ver:4.0.0,special_id:52550000}\n" + "{product_name:Archer C7,product_ver:4.0.0,special_id:54570000}\n" + "{product_name:Archer C7,product_ver:4.0.0,special_id:55530000}\n" + "{product_name:Archer C7,product_ver:4.0.0,special_id:43410000}\n", + .support_trail = '\x00', + .soft_ver = "soft_ver:1.0.0\n", + + /** + We use a bigger os-image partition than the stock images (and thus + smaller file-system), as our kernel doesn't fit in the stock firmware's + 1MB os-image. + */ + .partitions = { + {"factory-boot", 0x00000, 0x20000}, + {"fs-uboot", 0x20000, 0x20000}, + {"os-image", 0x40000, 0x180000}, /* Stock: base 0x40000 size 0x120000 */ + {"file-system", 0x1c0000, 0xd40000}, /* Stock: base 0x160000 size 0xda0000 */ + {"default-mac", 0xf00000, 0x00200}, + {"pin", 0xf00200, 0x00200}, + {"device-id", 0xf00400, 0x00100}, + {"product-info", 0xf00500, 0x0fb00}, + {"soft-version", 0xf10000, 0x00100}, + {"extra-para", 0xf11000, 0x01000}, + {"support-list", 0xf12000, 0x0a000}, + {"profile", 0xf1c000, 0x04000}, + {"default-config", 0xf20000, 0x10000}, + {"user-config", 0xf30000, 0x40000}, + {"qos-db", 0xf70000, 0x40000}, + {"certificate", 0xfb0000, 0x10000}, + {"partition-table", 0xfc0000, 0x10000}, + {"log", 0xfd0000, 0x20000}, + {"radio", 0xff0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system", + }, + + /** Firmware layout for the C7 v5*/ + { + .id = "ARCHER-C7-V5", + .support_list = + "SupportList:\n" + "{product_name:Archer C7,product_ver:5.0.0,special_id:00000000}\n" + "{product_name:Archer C7,product_ver:5.0.0,special_id:55530000}\n", + + .support_trail = '\x00', + .soft_ver = "soft_ver:1.0.0\n", + + /** + We use a bigger os-image partition than the stock images (and thus + smaller file-system), as our kernel doesn't fit in the stock firmware's + 1MB os-image. + */ + .partitions = { + {"factory-boot", 0x00000, 0x20000}, + {"fs-uboot", 0x20000, 0x20000}, + {"partition-table", 0x40000, 0x10000}, + {"radio", 0x50000, 0x10000}, + {"default-mac", 0x60000, 0x00200}, + {"pin", 0x60200, 0x00200}, + {"device-id", 0x60400, 0x00100}, + {"product-info", 0x60500, 0x0fb00}, + {"soft-version", 0x70000, 0x01000}, + {"extra-para", 0x71000, 0x01000}, + {"support-list", 0x72000, 0x0a000}, + {"profile", 0x7c000, 0x04000}, + {"user-config", 0x80000, 0x40000}, + + + {"os-image", 0xc0000, 0x180000}, /* Stock: base 0xc0000 size 0x120000 */ + {"file-system", 0x240000, 0xd80000}, /* Stock: base 0x1e0000 size 0xde0000 */ + + {"log", 0xfc0000, 0x20000}, + {"certificate", 0xfe0000, 0x10000}, + {"default-config", 0xff0000, 0x10000}, + {NULL, 0, 0} + + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system", + }, + + /** Firmware layout for the C9 */ + { + .id = "ARCHERC9", + .vendor = "", + .support_list = + "SupportList:\n" + "{product_name:ArcherC9," + "product_ver:1.0.0," + "special_id:00000000}\n", + .support_trail = '\x00', + .soft_ver = NULL, + + .partitions = { + {"fs-uboot", 0x00000, 0x40000}, + {"os-image", 0x40000, 0x200000}, + {"file-system", 0x240000, 0xc00000}, + {"default-mac", 0xe40000, 0x00200}, + {"pin", 0xe40200, 0x00200}, + {"product-info", 0xe40400, 0x00200}, + {"partition-table", 0xe50000, 0x10000}, + {"soft-version", 0xe60000, 0x00200}, + {"support-list", 0xe61000, 0x0f000}, + {"profile", 0xe70000, 0x10000}, + {"default-config", 0xe80000, 0x10000}, + {"user-config", 0xe90000, 0x50000}, + {"log", 0xee0000, 0x100000}, + {"radio_bk", 0xfe0000, 0x10000}, + {"radio", 0xff0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + + /** Firmware layout for the EAP120 */ + { + .id = "EAP120", + .vendor = "EAP120(TP-LINK|UN|N300-2):1.0\r\n", + .support_list = + "SupportList:\r\n" + "EAP120(TP-LINK|UN|N300-2):1.0\r\n", + .support_trail = '\xff', + .soft_ver = NULL, + + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"partition-table", 0x20000, 0x02000}, + {"default-mac", 0x30000, 0x00020}, + {"support-list", 0x31000, 0x00100}, + {"product-info", 0x31100, 0x00100}, + {"soft-version", 0x32000, 0x00100}, + {"os-image", 0x40000, 0x180000}, + {"file-system", 0x1c0000, 0x600000}, + {"user-config", 0x7c0000, 0x10000}, + {"backup-config", 0x7d0000, 0x10000}, + {"log", 0x7e0000, 0x10000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + + /** Firmware layout for the TL-WA850RE v2 */ + { + .id = "TLWA850REV2", + .vendor = "", + .support_list = + "SupportList:\n" + "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n" + "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n" + "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n" + "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n" + "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n" + "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n" + "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n" + "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n" + "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n" + "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n", + .support_trail = '\x00', + .soft_ver = NULL, + + /** + 576KB were moved from file-system to os-image + in comparison to the stock image + */ + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"os-image", 0x20000, 0x150000}, + {"file-system", 0x170000, 0x240000}, + {"partition-table", 0x3b0000, 0x02000}, + {"default-mac", 0x3c0000, 0x00020}, + {"pin", 0x3c0100, 0x00020}, + {"product-info", 0x3c1000, 0x01000}, + {"soft-version", 0x3c2000, 0x00100}, + {"support-list", 0x3c3000, 0x01000}, + {"profile", 0x3c4000, 0x08000}, + {"user-config", 0x3d0000, 0x10000}, + {"default-config", 0x3e0000, 0x10000}, + {"radio", 0x3f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + + /** Firmware layout for the TL-WA855RE v1 */ + { + .id = "TLWA855REV1", + .vendor = "", + .support_list = + "SupportList:\n" + "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n" + "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n" + "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n" + "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n" + "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n" + "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n" + "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n" + "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n" + "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n", + .support_trail = '\x00', + .soft_ver = NULL, + + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"os-image", 0x20000, 0x150000}, + {"file-system", 0x170000, 0x240000}, + {"partition-table", 0x3b0000, 0x02000}, + {"default-mac", 0x3c0000, 0x00020}, + {"pin", 0x3c0100, 0x00020}, + {"product-info", 0x3c1000, 0x01000}, + {"soft-version", 0x3c2000, 0x00100}, + {"support-list", 0x3c3000, 0x01000}, + {"profile", 0x3c4000, 0x08000}, + {"user-config", 0x3d0000, 0x10000}, + {"default-config", 0x3e0000, 0x10000}, + {"radio", 0x3f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + + /** Firmware layout for the TL-WR1043 v5 */ + { + .id = "TLWR1043NV5", + .vendor = "", + .support_list = + "SupportList:\n" + "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n" + "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n", + .support_trail = '\x00', + .soft_ver = "soft_ver:1.0.0\n", + .partitions = { + {"factory-boot", 0x00000, 0x20000}, + {"fs-uboot", 0x20000, 0x20000}, + {"os-image", 0x40000, 0x180000}, + {"file-system", 0x1c0000, 0xd40000}, + {"default-mac", 0xf00000, 0x00200}, + {"pin", 0xf00200, 0x00200}, + {"device-id", 0xf00400, 0x00100}, + {"product-info", 0xf00500, 0x0fb00}, + {"soft-version", 0xf10000, 0x01000}, + {"extra-para", 0xf11000, 0x01000}, + {"support-list", 0xf12000, 0x0a000}, + {"profile", 0xf1c000, 0x04000}, + {"default-config", 0xf20000, 0x10000}, + {"user-config", 0xf30000, 0x40000}, + {"qos-db", 0xf70000, 0x40000}, + {"certificate", 0xfb0000, 0x10000}, + {"partition-table", 0xfc0000, 0x10000}, + {"log", 0xfd0000, 0x20000}, + {"radio", 0xff0000, 0x10000}, + {NULL, 0, 0} + }, + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + + /** Firmware layout for the TL-WR1043 v4 */ + { + .id = "TLWR1043NDV4", + .vendor = "", + .support_list = + "SupportList:\n" + "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n", + .support_trail = '\x00', + .soft_ver = NULL, + + /* We're using a dynamic kernel/rootfs split here */ + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"firmware", 0x20000, 0xf30000}, + {"default-mac", 0xf50000, 0x00200}, + {"pin", 0xf50200, 0x00200}, + {"product-info", 0xf50400, 0x0fc00}, + {"soft-version", 0xf60000, 0x0b000}, + {"support-list", 0xf6b000, 0x04000}, + {"profile", 0xf70000, 0x04000}, + {"default-config", 0xf74000, 0x0b000}, + {"user-config", 0xf80000, 0x40000}, + {"partition-table", 0xfc0000, 0x10000}, + {"log", 0xfd0000, 0x20000}, + {"radio", 0xff0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + + /** Firmware layout for the TL-WR902AC v1 */ + { + .id = "TL-WR902AC-V1", + .vendor = "", + .support_list = + "SupportList:\n" + "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n" + "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n", + .support_trail = '\x00', + .soft_ver = NULL, + + /** + 384KB were moved from file-system to os-image + in comparison to the stock image + */ + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"os-image", 0x20000, 0x180000}, + {"file-system", 0x1a0000, 0x5b0000}, + {"default-mac", 0x750000, 0x00200}, + {"pin", 0x750200, 0x00200}, + {"product-info", 0x750400, 0x0fc00}, + {"soft-version", 0x760000, 0x0b000}, + {"support-list", 0x76b000, 0x04000}, + {"profile", 0x770000, 0x04000}, + {"default-config", 0x774000, 0x0b000}, + {"user-config", 0x780000, 0x40000}, + {"partition-table", 0x7c0000, 0x10000}, + {"log", 0x7d0000, 0x20000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system", + }, + + /** Firmware layout for the TL-WR942N V1 */ + { + .id = "TLWR942NV1", + .vendor = "", + .support_list = + "SupportList:\r\n" + "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n" + "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n", + .support_trail = '\x00', + .soft_ver = NULL, + + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"os-image", 0x20000, 0x180000}, + {"file-system", 0x1a0000, 0xca0000}, + {"default-mac", 0xe40000, 0x00200}, + {"pin", 0xe40200, 0x00200}, + {"product-info", 0xe40400, 0x0fc00}, + {"partition-table", 0xe50000, 0x10000}, + {"soft-version", 0xe60000, 0x10000}, + {"support-list", 0xe70000, 0x10000}, + {"profile", 0xe80000, 0x10000}, + {"default-config", 0xe90000, 0x10000}, + {"user-config", 0xea0000, 0x40000}, + {"qos-db", 0xee0000, 0x40000}, + {"certificate", 0xf20000, 0x10000}, + {"usb-config", 0xfb0000, 0x10000}, + {"log", 0xfc0000, 0x20000}, + {"radio-bk", 0xfe0000, 0x10000}, + {"radio", 0xff0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system", + }, + + /** Firmware layout for the RE350 v1 */ + { + .id = "RE350-V1", + .vendor = "", + .support_list = + "SupportList:\n" + "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n" + "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n" + "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n" + "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n" + "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n" + "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n" + "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n", + .support_trail = '\x00', + .soft_ver = NULL, + + /** We're using a dynamic kernel/rootfs split here */ + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"firmware", 0x20000, 0x5e0000}, + {"partition-table", 0x600000, 0x02000}, + {"default-mac", 0x610000, 0x00020}, + {"pin", 0x610100, 0x00020}, + {"product-info", 0x611100, 0x01000}, + {"soft-version", 0x620000, 0x01000}, + {"support-list", 0x621000, 0x01000}, + {"profile", 0x622000, 0x08000}, + {"user-config", 0x630000, 0x10000}, + {"default-config", 0x640000, 0x10000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + + /** Firmware layout for the RE355 */ + { + .id = "RE355", + .vendor = "", + .support_list = + "SupportList:\r\n" + "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n" + "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n" + "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n" + "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n" + "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n" + "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n" + "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n" + "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n", + .support_trail = '\x00', + .soft_ver = NULL, + + /** + The flash partition table for RE355; + it is almost the same as the one used by the stock images, + 576KB were moved from file-system to os-image. + */ + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"os-image", 0x20000, 0x180000}, + {"file-system", 0x1a0000, 0x460000}, + {"partition-table", 0x600000, 0x02000}, + {"default-mac", 0x610000, 0x00020}, + {"pin", 0x610100, 0x00020}, + {"product-info", 0x611100, 0x01000}, + {"soft-version", 0x620000, 0x01000}, + {"support-list", 0x621000, 0x01000}, + {"profile", 0x622000, 0x08000}, + {"user-config", 0x630000, 0x10000}, + {"default-config", 0x640000, 0x10000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + + /** Firmware layout for the RE450 */ + { + .id = "RE450", + .vendor = "", + .support_list = + "SupportList:\r\n" + "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n" + "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n" + "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n" + "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n" + "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n" + "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n" + "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n" + "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n", + .support_trail = '\x00', + .soft_ver = NULL, + + /** + The flash partition table for RE450; + it is almost the same as the one used by the stock images, + 576KB were moved from file-system to os-image. + */ + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"os-image", 0x20000, 0x180000}, + {"file-system", 0x1a0000, 0x460000}, + {"partition-table", 0x600000, 0x02000}, + {"default-mac", 0x610000, 0x00020}, + {"pin", 0x610100, 0x00020}, + {"product-info", 0x611100, 0x01000}, + {"soft-version", 0x620000, 0x01000}, + {"support-list", 0x621000, 0x01000}, + {"profile", 0x622000, 0x08000}, + {"user-config", 0x630000, 0x10000}, + {"default-config", 0x640000, 0x10000}, + {"radio", 0x7f0000, 0x10000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + + /** Firmware layout for the RE450 v2 */ + { + .id = "RE450-V2", + .vendor = "", + .support_list = + "SupportList:\r\n" + "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n" + "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n" + "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n" + "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n" + "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n" + "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n" + "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n" + "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n" + "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n", + .support_trail = '\x00', + .soft_ver = NULL, + + /* We're using a dynamic kernel/rootfs split here */ + .partitions = { + {"fs-uboot", 0x00000, 0x20000}, + {"firmware", 0x20000, 0x5e0000}, + {"partition-table", 0x600000, 0x02000}, + {"default-mac", 0x610000, 0x00020}, + {"pin", 0x610100, 0x00020}, + {"product-info", 0x611100, 0x01000}, + {"soft-version", 0x620000, 0x01000}, + {"support-list", 0x621000, 0x01000}, + {"profile", 0x622000, 0x08000}, + {"user-config", 0x630000, 0x10000}, + {"default-config", 0x640000, 0x10000}, + {"radio", 0x7f0000, 0x10000}, + + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + + {} +}; + +#define error(_ret, _errno, _str, ...) \ + do { \ + fprintf(stderr, _str ": %s\n", ## __VA_ARGS__, \ + strerror(_errno)); \ + if (_ret) \ + exit(_ret); \ + } while (0) + + +/** Stores a uint32 as big endian */ +static inline void put32(uint8_t *buf, uint32_t val) { + buf[0] = val >> 24; + buf[1] = val >> 16; + buf[2] = val >> 8; + buf[3] = val; +} + +/** Allocates a new image partition */ +static struct image_partition_entry alloc_image_partition(const char *name, size_t len) { + struct image_partition_entry entry = {name, len, malloc(len)}; + if (!entry.data) + error(1, errno, "malloc"); + + return entry; +} + +/** Frees an image partition */ +static void free_image_partition(struct image_partition_entry entry) { + free(entry.data); +} + +static time_t source_date_epoch = -1; +static void set_source_date_epoch() { + char *env = getenv("SOURCE_DATE_EPOCH"); + char *endptr = env; + errno = 0; + if (env && *env) { + source_date_epoch = strtoull(env, &endptr, 10); + if (errno || (endptr && *endptr != '\0')) { + fprintf(stderr, "Invalid SOURCE_DATE_EPOCH"); + exit(1); + } + } +} + +/** Generates the partition-table partition */ +static struct image_partition_entry make_partition_table(const struct flash_partition_entry *p) { + struct image_partition_entry entry = alloc_image_partition("partition-table", 0x800); + + char *s = (char *)entry.data, *end = (char *)(s+entry.size); + + *(s++) = 0x00; + *(s++) = 0x04; + *(s++) = 0x00; + *(s++) = 0x00; + + size_t i; + for (i = 0; p[i].name; i++) { + size_t len = end-s; + size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n", p[i].name, p[i].base, p[i].size); + + if (w > len-1) + error(1, 0, "flash partition table overflow?"); + + s += w; + } + + s++; + + memset(s, 0xff, end-s); + + return entry; +} + + +/** Generates a binary-coded decimal representation of an integer in the range [0, 99] */ +static inline uint8_t bcd(uint8_t v) { + return 0x10 * (v/10) + v%10; +} + + +/** Generates the soft-version partition */ +static struct image_partition_entry make_soft_version(uint32_t rev) { + struct image_partition_entry entry = alloc_image_partition("soft-version", sizeof(struct soft_version)); + struct soft_version *s = (struct soft_version *)entry.data; + + time_t t; + + if (source_date_epoch != -1) + t = source_date_epoch; + else if (time(&t) == (time_t)(-1)) + error(1, errno, "time"); + + struct tm *tm = localtime(&t); + + s->magic = htonl(0x0000000c); + s->zero = 0; + s->pad1 = 0xff; + + s->version_major = 0; + s->version_minor = 0; + s->version_patch = 0; + + s->year_hi = bcd((1900+tm->tm_year)/100); + s->year_lo = bcd(tm->tm_year%100); + s->month = bcd(tm->tm_mon+1); + s->day = bcd(tm->tm_mday); + s->rev = htonl(rev); + + s->pad2 = 0xff; + + return entry; +} + +static struct image_partition_entry make_soft_version_from_string(const char *soft_ver) { + /** String length _including_ the terminating zero byte */ + uint32_t ver_len = strlen(soft_ver) + 1; + /** Partition contains 64 bit header, the version string, and one additional null byte */ + size_t partition_len = 2*sizeof(uint32_t) + ver_len + 1; + struct image_partition_entry entry = alloc_image_partition("soft-version", partition_len); + + uint32_t *len = (uint32_t *)entry.data; + len[0] = htonl(ver_len); + len[1] = 0; + memcpy(&len[2], soft_ver, ver_len); + + entry.data[partition_len - 1] = 0; + + return entry; +} + +/** Generates the support-list partition */ +static struct image_partition_entry make_support_list(struct device_info *info) { + size_t len = strlen(info->support_list); + struct image_partition_entry entry = alloc_image_partition("support-list", len + 9); + + put32(entry.data, len); + memset(entry.data+4, 0, 4); + memcpy(entry.data+8, info->support_list, len); + entry.data[len+8] = info->support_trail; + + return entry; +} + +/** Creates a new image partition with an arbitrary name from a file */ +static struct image_partition_entry read_file(const char *part_name, const char *filename, bool add_jffs2_eof, struct flash_partition_entry *file_system_partition) { + struct stat statbuf; + + if (stat(filename, &statbuf) < 0) + error(1, errno, "unable to stat file `%s'", filename); + + size_t len = statbuf.st_size; + + if (add_jffs2_eof) + if (file_system_partition) + len = ALIGN(len + file_system_partition->base, 0x10000) + sizeof(jffs2_eof_mark) - file_system_partition->base; + else + len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark); + + struct image_partition_entry entry = alloc_image_partition(part_name, len); + + FILE *file = fopen(filename, "rb"); + if (!file) + error(1, errno, "unable to open file `%s'", filename); + + if (fread(entry.data, statbuf.st_size, 1, file) != 1) + error(1, errno, "unable to read file `%s'", filename); + + if (add_jffs2_eof) { + uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size; + + memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark)); + memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark)); + } + + fclose(file); + + return entry; +} + +/** Creates a new image partition from arbitrary data */ +static struct image_partition_entry put_data(const char *part_name, const char *datain, size_t len) { + + struct image_partition_entry entry = alloc_image_partition(part_name, len); + + memcpy(entry.data, datain, len); + + return entry; +} + +/** + Copies a list of image partitions into an image buffer and generates the image partition table while doing so + + Example image partition table: + + fwup-ptn partition-table base 0x00800 size 0x00800 + fwup-ptn os-image base 0x01000 size 0x113b45 + fwup-ptn file-system base 0x114b45 size 0x1d0004 + fwup-ptn support-list base 0x2e4b49 size 0x000d1 + + Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"), + the end of the partition table is marked with a zero byte. + + The firmware image must contain at least the partition-table and support-list partitions + to be accepted. There aren't any alignment constraints for the image partitions. + + The partition-table partition contains the actual flash layout; partitions + from the image partition table are mapped to the corresponding flash partitions during + the firmware upgrade. The support-list partition contains a list of devices supported by + the firmware image. + + The base offsets in the firmware partition table are relative to the end + of the vendor information block, so the partition-table partition will + actually start at offset 0x1814 of the image. + + I think partition-table must be the first partition in the firmware image. +*/ +static void put_partitions(uint8_t *buffer, const struct flash_partition_entry *flash_parts, const struct image_partition_entry *parts) { + size_t i, j; + char *image_pt = (char *)buffer, *end = image_pt + 0x800; + + size_t base = 0x800; + for (i = 0; parts[i].name; i++) { + for (j = 0; flash_parts[j].name; j++) { + if (!strcmp(flash_parts[j].name, parts[i].name)) { + if (parts[i].size > flash_parts[j].size) + error(1, 0, "%s partition too big (more than %u bytes)", flash_parts[j].name, (unsigned)flash_parts[j].size); + break; + } + } + + assert(flash_parts[j].name); + + memcpy(buffer + base, parts[i].data, parts[i].size); + + size_t len = end-image_pt; + size_t w = snprintf(image_pt, len, "fwup-ptn %s base 0x%05x size 0x%05x\t\r\n", parts[i].name, (unsigned)base, (unsigned)parts[i].size); + + if (w > len-1) + error(1, 0, "image partition table overflow?"); + + image_pt += w; + + base += parts[i].size; + } +} + +/** Generates and writes the image MD5 checksum */ +static void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) { + MD5_CTX ctx; + + MD5_Init(&ctx); + MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt)); + MD5_Update(&ctx, buffer, len); + MD5_Final(md5, &ctx); +} + + +/** + Generates the firmware image in factory format + + Image format: + + Bytes (hex) Usage + ----------- ----- + 0000-0003 Image size (4 bytes, big endian) + 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14) + 0014-0017 Vendor information length (without padding) (4 bytes, big endian) + 0018-1013 Vendor information (4092 bytes, padded with 0xff; there seem to be older + (VxWorks-based) TP-LINK devices which use a smaller vendor information block) + 1014-1813 Image partition table (2048 bytes, padded with 0xff) + 1814-xxxx Firmware partitions +*/ +static void * generate_factory_image(struct device_info *info, const struct image_partition_entry *parts, size_t *len) { + *len = 0x1814; + + size_t i; + for (i = 0; parts[i].name; i++) + *len += parts[i].size; + + uint8_t *image = malloc(*len); + if (!image) + error(1, errno, "malloc"); + + memset(image, 0xff, *len); + put32(image, *len); + + if (info->vendor) { + size_t vendor_len = strlen(info->vendor); + put32(image+0x14, vendor_len); + memcpy(image+0x18, info->vendor, vendor_len); + } + + put_partitions(image + 0x1014, info->partitions, parts); + put_md5(image+0x04, image+0x14, *len-0x14); + + return image; +} + +/** + Generates the firmware image in sysupgrade format + + This makes some assumptions about the provided flash and image partition tables and + should be generalized when TP-LINK starts building its safeloader into hardware with + different flash layouts. +*/ +static void * generate_sysupgrade_image(struct device_info *info, const struct image_partition_entry *image_parts, size_t *len) { + size_t i, j; + size_t flash_first_partition_index = 0; + size_t flash_last_partition_index = 0; + const struct flash_partition_entry *flash_first_partition = NULL; + const struct flash_partition_entry *flash_last_partition = NULL; + const struct image_partition_entry *image_last_partition = NULL; + + /** Find first and last partitions */ + for (i = 0; info->partitions[i].name; i++) { + if (!strcmp(info->partitions[i].name, info->first_sysupgrade_partition)) { + flash_first_partition = &info->partitions[i]; + flash_first_partition_index = i; + } else if (!strcmp(info->partitions[i].name, info->last_sysupgrade_partition)) { + flash_last_partition = &info->partitions[i]; + flash_last_partition_index = i; + } + } + + assert(flash_first_partition && flash_last_partition); + assert(flash_first_partition_index < flash_last_partition_index); + + /** Find last partition from image to calculate needed size */ + for (i = 0; image_parts[i].name; i++) { + if (!strcmp(image_parts[i].name, info->last_sysupgrade_partition)) { + image_last_partition = &image_parts[i]; + break; + } + } + + assert(image_last_partition); + + *len = flash_last_partition->base - flash_first_partition->base + image_last_partition->size; + + uint8_t *image = malloc(*len); + if (!image) + error(1, errno, "malloc"); + + memset(image, 0xff, *len); + + for (i = flash_first_partition_index; i <= flash_last_partition_index; i++) { + for (j = 0; image_parts[j].name; j++) { + if (!strcmp(info->partitions[i].name, image_parts[j].name)) { + if (image_parts[j].size > info->partitions[i].size) + error(1, 0, "%s partition too big (more than %u bytes)", info->partitions[i].name, (unsigned)info->partitions[i].size); + memcpy(image + info->partitions[i].base - flash_first_partition->base, image_parts[j].data, image_parts[j].size); + break; + } + + assert(image_parts[j].name); + } + } + + return image; +} + +/** Generates an image according to a given layout and writes it to a file */ +static void build_image(const char *output, + const char *kernel_image, + const char *rootfs_image, + uint32_t rev, + bool add_jffs2_eof, + bool sysupgrade, + struct device_info *info) { + + size_t i; + + struct image_partition_entry parts[7] = {}; + + struct flash_partition_entry *firmware_partition = NULL; + struct flash_partition_entry *os_image_partition = NULL; + struct flash_partition_entry *file_system_partition = NULL; + size_t firmware_partition_index = 0; + + for (i = 0; info->partitions[i].name; i++) { + if (!strcmp(info->partitions[i].name, "firmware")) + { + firmware_partition = &info->partitions[i]; + firmware_partition_index = i; + } + } + + if (firmware_partition) + { + os_image_partition = &info->partitions[firmware_partition_index]; + file_system_partition = &info->partitions[firmware_partition_index + 1]; + + struct stat kernel; + if (stat(kernel_image, &kernel) < 0) + error(1, errno, "unable to stat file `%s'", kernel_image); + + if (kernel.st_size > firmware_partition->size) + error(1, 0, "kernel overflowed firmware partition\n"); + + for (i = MAX_PARTITIONS-1; i >= firmware_partition_index + 1; i--) + info->partitions[i+1] = info->partitions[i]; + + file_system_partition->name = "file-system"; + file_system_partition->base = firmware_partition->base + kernel.st_size; + + /* Align partition start to erase blocks for factory images only */ + if (!sysupgrade) + file_system_partition->base = ALIGN(firmware_partition->base + kernel.st_size, 0x10000); + + file_system_partition->size = firmware_partition->size - file_system_partition->base; + + os_image_partition->name = "os-image"; + os_image_partition->size = kernel.st_size; + } + + parts[0] = make_partition_table(info->partitions); + if (info->soft_ver) + parts[1] = make_soft_version_from_string(info->soft_ver); + else + parts[1] = make_soft_version(rev); + + parts[2] = make_support_list(info); + parts[3] = read_file("os-image", kernel_image, false, NULL); + parts[4] = read_file("file-system", rootfs_image, add_jffs2_eof, file_system_partition); + + /* Some devices need the extra-para partition to accept the firmware */ + if (strcasecmp(info->id, "ARCHER-C25-V1") == 0 || + strcasecmp(info->id, "ARCHER-C59-V2") == 0 || + strcasecmp(info->id, "ARCHER-C60-V2") == 0 || + strcasecmp(info->id, "TLWR1043NV5") == 0) { + const char mdat[11] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; + parts[5] = put_data("extra-para", mdat, 11); + } else if (strcasecmp(info->id, "ARCHER-C7-V4") == 0 || strcasecmp(info->id, "ARCHER-C7-V5") == 0) { + const char mdat[11] = {0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0xca, 0x00, 0x01, 0x00, 0x00}; + parts[5] = put_data("extra-para", mdat, 11); + } + + size_t len; + void *image; + if (sysupgrade) + image = generate_sysupgrade_image(info, parts, &len); + else + image = generate_factory_image(info, parts, &len); + + FILE *file = fopen(output, "wb"); + if (!file) + error(1, errno, "unable to open output file"); + + if (fwrite(image, len, 1, file) != 1) + error(1, 0, "unable to write output file"); + + fclose(file); + + free(image); + + for (i = 0; parts[i].name; i++) + free_image_partition(parts[i]); +} + +/** Usage output */ +static void usage(const char *argv0) { + fprintf(stderr, + "Usage: %s [OPTIONS...]\n" + "\n" + "Options:\n" + " -h show this help\n" + "\n" + "Create a new image:\n" + " -B <board> create image for the board specified with <board>\n" + " -k <file> read kernel image from the file <file>\n" + " -r <file> read rootfs image from the file <file>\n" + " -o <file> write output to the file <file>\n" + " -V <rev> sets the revision number to <rev>\n" + " -j add jffs2 end-of-filesystem markers\n" + " -S create sysupgrade instead of factory image\n" + "Extract an old image:\n" + " -x <file> extract all oem firmware partition\n" + " -d <dir> destination to extract the firmware partition\n" + " -z <file> convert an oem firmware into a sysupgade file. Use -o for output file\n", + argv0 + ); +}; + + +static struct device_info *find_board(const char *id) +{ + struct device_info *board = NULL; + + for (board = boards; board->id != NULL; board++) + if (strcasecmp(id, board->id) == 0) + return board; + + return NULL; +} + +static int add_flash_partition( + struct flash_partition_entry *part_list, + size_t max_entries, + const char *name, + unsigned long base, + unsigned long size) +{ + int ptr; + /* check if the list has a free entry */ + for (ptr = 0; ptr < max_entries; ptr++, part_list++) { + if (part_list->name == NULL && + part_list->base == 0 && + part_list->size == 0) + break; + } + + if (ptr == max_entries) { + error(1, 0, "No free flash part entry available."); + } + + part_list->name = calloc(1, strlen(name) + 1); + if (!part_list->name) { + error(1, 0, "Unable to allocate memory"); + } + + memcpy((char *)part_list->name, name, strlen(name)); + part_list->base = base; + part_list->size = size; + + return 0; +} + +/** read the partition table into struct flash_partition_entry */ +static int read_partition_table( + FILE *file, long offset, + struct flash_partition_entry *entries, size_t max_entries, + int type) +{ + char buf[2048]; + char *ptr, *end; + const char *parthdr = NULL; + const char *fwuphdr = "fwup-ptn"; + const char *flashhdr = "partition"; + + /* TODO: search for the partition table */ + + switch(type) { + case 0: + parthdr = fwuphdr; + break; + case 1: + parthdr = flashhdr; + break; + default: + error(1, 0, "Invalid partition table"); + } + + if (fseek(file, offset, SEEK_SET) < 0) + error(1, errno, "Can not seek in the firmware"); + + if (fread(buf, 1, 2048, file) < 0) + error(1, errno, "Can not read fwup-ptn from the firmware"); + + buf[2047] = '\0'; + + /* look for the partition header */ + if (memcmp(buf, parthdr, strlen(parthdr)) != 0) { + fprintf(stderr, "DEBUG: can not find fwuphdr\n"); + return 1; + } + + ptr = buf; + end = buf + sizeof(buf); + while ((ptr + strlen(parthdr)) < end && + memcmp(ptr, parthdr, strlen(parthdr)) == 0) { + char *end_part; + char *end_element; + + char name[32] = { 0 }; + int name_len = 0; + unsigned long base = 0; + unsigned long size = 0; + + end_part = memchr(ptr, '\n', (end - ptr)); + if (end_part == NULL) { + /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */ + break; + } + + for (int i = 0; i <= 4; i++) { + if (end_part <= ptr) + break; + + end_element = memchr(ptr, 0x20, (end_part - ptr)); + if (end_element == NULL) { + error(1, errno, "Ignoring the rest of the partition entries."); + break; + } + + switch (i) { + /* partition header */ + case 0: + ptr = end_element + 1; + continue; + /* name */ + case 1: + name_len = (end_element - ptr) > 31 ? 31 : (end_element - ptr); + strncpy(name, ptr, name_len); + name[name_len] = '\0'; + ptr = end_element + 1; + continue; + + /* string "base" */ + case 2: + ptr = end_element + 1; + continue; + + /* actual base */ + case 3: + base = strtoul(ptr, NULL, 16); + ptr = end_element + 1; + continue; + + /* string "size" */ + case 4: + ptr = end_element + 1; + /* actual size. The last element doesn't have a sepeartor */ + size = strtoul(ptr, NULL, 16); + /* the part ends with 0x09, 0x0d, 0x0a */ + ptr = end_part + 1; + add_flash_partition(entries, max_entries, name, base, size); + continue; + } + } + } + + return 0; +} + +static void write_partition( + FILE *input_file, + size_t firmware_offset, + struct flash_partition_entry *entry, + FILE *output_file) +{ + char buf[4096]; + size_t offset; + + fseek(input_file, entry->base + firmware_offset, SEEK_SET); + + for (offset = 0; sizeof(buf) + offset <= entry->size; offset += sizeof(buf)) { + if (fread(buf, sizeof(buf), 1, input_file) < 0) + error(1, errno, "Can not read partition from input_file"); + + if (fwrite(buf, sizeof(buf), 1, output_file) < 0) + error(1, errno, "Can not write partition to output_file"); + } + /* write last chunk smaller than buffer */ + if (offset < entry->size) { + offset = entry->size - offset; + if (fread(buf, offset, 1, input_file) < 0) + error(1, errno, "Can not read partition from input_file"); + if (fwrite(buf, offset, 1, output_file) < 0) + error(1, errno, "Can not write partition to output_file"); + } +} + +static int extract_firmware_partition(FILE *input_file, size_t firmware_offset, struct flash_partition_entry *entry, const char *output_directory) +{ + FILE *output_file; + char output[PATH_MAX]; + + snprintf(output, PATH_MAX, "%s/%s", output_directory, entry->name); + output_file = fopen(output, "wb+"); + if (output_file == NULL) { + error(1, errno, "Can not open output file %s", output); + } + + write_partition(input_file, firmware_offset, entry, output_file); + + fclose(output_file); + + return 0; +} + +/** extract all partitions from the firmware file */ +static int extract_firmware(const char *input, const char *output_directory) +{ + struct flash_partition_entry entries[16] = { 0 }; + size_t max_entries = 16; + size_t firmware_offset = 0x1014; + FILE *input_file; + + struct stat statbuf; + + /* check input file */ + if (stat(input, &statbuf)) { + error(1, errno, "Can not read input firmware %s", input); + } + + /* check if output directory exists */ + if (stat(output_directory, &statbuf)) { + error(1, errno, "Failed to stat output directory %s", output_directory); + } + + if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { + error(1, errno, "Given output directory is not a directory %s", output_directory); + } + + input_file = fopen(input, "rb"); + + if (read_partition_table(input_file, firmware_offset, entries, 16, 0) != 0) { + error(1, 0, "Error can not read the partition table (fwup-ptn)"); + } + + for (int i = 0; i < max_entries; i++) { + if (entries[i].name == NULL && + entries[i].base == 0 && + entries[i].size == 0) + continue; + + extract_firmware_partition(input_file, firmware_offset, &entries[i], output_directory); + } + + return 0; +} + +static struct flash_partition_entry *find_partition( + struct flash_partition_entry *entries, size_t max_entries, + const char *name, const char *error_msg) +{ + for (int i = 0; i < max_entries; i++, entries++) { + if (strcmp(entries->name, name) == 0) + return entries; + } + + error(1, 0, "%s", error_msg); + return NULL; +} + +static void write_ff(FILE *output_file, size_t size) +{ + char buf[4096]; + int offset; + + memset(buf, 0xff, sizeof(buf)); + + for (offset = 0; offset + sizeof(buf) < size ; offset += sizeof(buf)) { + if (fwrite(buf, sizeof(buf), 1, output_file) < 0) + error(1, errno, "Can not write 0xff to output_file"); + } + + /* write last chunk smaller than buffer */ + if (offset < size) { + offset = size - offset; + if (fwrite(buf, offset, 1, output_file) < 0) + error(1, errno, "Can not write partition to output_file"); + } +} + +static void convert_firmware(const char *input, const char *output) +{ + struct flash_partition_entry fwup[MAX_PARTITIONS] = { 0 }; + struct flash_partition_entry flash[MAX_PARTITIONS] = { 0 }; + struct flash_partition_entry *fwup_os_image = NULL, *fwup_file_system = NULL; + struct flash_partition_entry *flash_os_image = NULL, *flash_file_system = NULL; + struct flash_partition_entry *fwup_partition_table = NULL; + size_t firmware_offset = 0x1014; + FILE *input_file, *output_file; + + struct stat statbuf; + + /* check input file */ + if (stat(input, &statbuf)) { + error(1, errno, "Can not read input firmware %s", input); + } + + input_file = fopen(input, "rb"); + if (!input_file) + error(1, 0, "Can not open input firmware %s", input); + + output_file = fopen(output, "wb"); + if (!output_file) + error(1, 0, "Can not open output firmware %s", output); + + if (read_partition_table(input_file, firmware_offset, fwup, MAX_PARTITIONS, 0) != 0) { + error(1, 0, "Error can not read the partition table (fwup-ptn)"); + } + + fwup_os_image = find_partition(fwup, MAX_PARTITIONS, + "os-image", "Error can not find os-image partition (fwup)"); + fwup_file_system = find_partition(fwup, MAX_PARTITIONS, + "file-system", "Error can not find file-system partition (fwup)"); + fwup_partition_table = find_partition(fwup, MAX_PARTITIONS, + "partition-table", "Error can not find partition-table partition"); + + /* the flash partition table has a 0x00000004 magic haeder */ + if (read_partition_table(input_file, firmware_offset + fwup_partition_table->base + 4, flash, MAX_PARTITIONS, 1) != 0) + error(1, 0, "Error can not read the partition table (flash)"); + + flash_os_image = find_partition(flash, MAX_PARTITIONS, + "os-image", "Error can not find os-image partition (flash)"); + flash_file_system = find_partition(flash, MAX_PARTITIONS, + "file-system", "Error can not find file-system partition (flash)"); + + /* write os_image to 0x0 */ + write_partition(input_file, firmware_offset, fwup_os_image, output_file); + write_ff(output_file, flash_os_image->size - fwup_os_image->size); + + /* write file-system behind os_image */ + fseek(output_file, flash_file_system->base - flash_os_image->base, SEEK_SET); + write_partition(input_file, firmware_offset, fwup_file_system, output_file); + write_ff(output_file, flash_file_system->size - fwup_file_system->size); + + fclose(output_file); + fclose(input_file); +} + +int main(int argc, char *argv[]) { + const char *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL; + const char *extract_image = NULL, *output_directory = NULL, *convert_image = NULL; + bool add_jffs2_eof = false, sysupgrade = false; + unsigned rev = 0; + struct device_info *info; + set_source_date_epoch(); + + while (true) { + int c; + + c = getopt(argc, argv, "B:k:r:o:V:jSh:x:d:z:"); + if (c == -1) + break; + + switch (c) { + case 'B': + board = optarg; + break; + + case 'k': + kernel_image = optarg; + break; + + case 'r': + rootfs_image = optarg; + break; + + case 'o': + output = optarg; + break; + + case 'V': + sscanf(optarg, "r%u", &rev); + break; + + case 'j': + add_jffs2_eof = true; + break; + + case 'S': + sysupgrade = true; + break; + + case 'h': + usage(argv[0]); + return 0; + + case 'd': + output_directory = optarg; + break; + + case 'x': + extract_image = optarg; + break; + + case 'z': + convert_image = optarg; + break; + + default: + usage(argv[0]); + return 1; + } + } + + if (extract_image || output_directory) { + if (!extract_image) + error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x"); + if (!output_directory) + error(1, 0, "Can not extract an image without output directory. Use -d <dir>"); + extract_firmware(extract_image, output_directory); + } else if (convert_image) { + if (!output) + error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>"); + convert_firmware(convert_image, output); + } else { + if (!board) + error(1, 0, "no board has been specified"); + if (!kernel_image) + error(1, 0, "no kernel image has been specified"); + if (!rootfs_image) + error(1, 0, "no rootfs image has been specified"); + if (!output) + error(1, 0, "no output filename has been specified"); + + info = find_board(board); + + if (info == NULL) + error(1, 0, "unsupported board %s", board); + + build_image(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade, info); + } + + return 0; +} diff --git a/tools/firmware-utils/src/trx.c b/tools/firmware-utils/src/trx.c index 8e95d98d7ae..dc5bb672aeb 100644 --- a/tools/firmware-utils/src/trx.c +++ b/tools/firmware-utils/src/trx.c @@ -68,7 +68,7 @@ uint32_t crc32buf(char *buf, size_t len); #define TRX_MAGIC 0x30524448 /* "HDR0" */ #define TRX_MAX_LEN 0x720000 -#define TRX_NO_HEADER 1 /* Do not write TRX header */ +#define TRX_NO_HEADER 1 /* Do not write TRX header */ struct trx_header { uint32_t magic; /* "HDR0" */ @@ -100,7 +100,7 @@ int main(int argc, char **argv) int c, i, append = 0; size_t n; ssize_t n2; - uint32_t cur_len, fsmark=0; + uint32_t cur_len, fsmark=0, magic; unsigned long maxlen = TRX_MAX_LEN; struct trx_header *p; char trx_version = 1; @@ -121,7 +121,7 @@ int main(int argc, char **argv) in = NULL; i = 0; - while ((c = getopt(argc, argv, "-:2o:m:a:x:b:f:A:F:")) != -1) { + while ((c = getopt(argc, argv, "-:2o:m:a:x:b:f:A:F:M:")) != -1) { switch (c) { case '2': /* take care that nothing was written to buf so far */ @@ -243,6 +243,15 @@ int main(int argc, char **argv) } break; + case 'M': + errno = 0; + magic = strtoul(optarg, &e, 0); + if (errno || (e == optarg) || *e) { + fprintf(stderr, "illegal numeric string\n"); + usage(); + } + p->magic = STORE32_LE(magic); + break; default: usage(); } @@ -262,7 +271,7 @@ int main(int argc, char **argv) cur_len += ROUND - n; } - /* for TRXv2 set bin-header Flags to 0xFF for CRC calculation like CFE does */ + /* for TRXv2 set bin-header Flags to 0xFF for CRC calculation like CFE does */ if (trx_version == 2) { if(cur_len - LOAD32_LE(p->offsets[3]) < sizeof(binheader)) { fprintf(stderr, "TRXv2 binheader too small!\n"); @@ -273,11 +282,10 @@ int main(int argc, char **argv) } p->crc32 = crc32buf((char *) &p->flag_version, - (fsmark)?fsmark:cur_len - offsetof(struct trx_header, flag_version)); + ((fsmark)?fsmark:cur_len) - offsetof(struct trx_header, flag_version)); p->crc32 = STORE32_LE(p->crc32); p->len = STORE32_LE((fsmark) ? fsmark : cur_len); - p->len = STORE32_LE(p->len); /* restore TRXv2 bin-header */ if (trx_version == 2) { @@ -290,7 +298,7 @@ int main(int argc, char **argv) } fclose(out); - + return EXIT_SUCCESS; } diff --git a/tools/firmware-utils/src/wndr3700.c b/tools/firmware-utils/src/wndr3700.c deleted file mode 100644 index 97b5f1d4558..00000000000 --- a/tools/firmware-utils/src/wndr3700.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * wndr3700.c - partially based on OpenWrt's add_header.c - * - * Copyright (C) 2009 Anael Orlinski <naouel@naouel.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License, - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - * The add_header utility used by various vendors preprends the buf - * image with a header containing a CRC32 value which is generated for the - * model id + reserved space for CRC32 + buf, then replaces the reserved - * area with the actual CRC32. This replacement tool mimics this behavior. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <string.h> -#include <netinet/in.h> -#include <inttypes.h> - -#define BPB 8 /* bits/byte */ - -#define WNDR3700_MAGIC_LEN 4 - -static uint32_t crc32[1<<BPB]; -static char *magic = "3700"; - -static void init_crc32() -{ - const uint32_t poly = ntohl(0x2083b8ed); - int n; - - for (n = 0; n < 1<<BPB; n++) { - uint32_t crc = n; - int bit; - - for (bit = 0; bit < BPB; bit++) - crc = (crc & 1) ? (poly ^ (crc >> 1)) : (crc >> 1); - crc32[n] = crc; - } -} - -static uint32_t crc32buf(unsigned char *buf, size_t len) -{ - uint32_t crc = 0xFFFFFFFF; - - for (; len; len--, buf++) - crc = crc32[(uint8_t)crc ^ *buf] ^ (crc >> BPB); - return ~crc; -} - -struct header { - unsigned char magic[WNDR3700_MAGIC_LEN]; - uint32_t crc; - unsigned char stuff[56]; -}; - -static void usage(const char *) __attribute__ (( __noreturn__ )); - -static void usage(const char *mess) -{ - fprintf(stderr, "Error: %s\n", mess); - fprintf(stderr, "Usage: wndr3700 input_file output_file [magic]\n"); - fprintf(stderr, "\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - off_t len; // of original buf - off_t buflen; // of the output file - int fd; - void *input_file; // pointer to the input file (mmmapped) - struct header header; - unsigned char *buf; // pointer to prefix + copy of original buf - - // verify parameters - - if (argc < 3) - usage("wrong number of arguments"); - - if (argc > 3) - magic = argv[3]; - - if (strlen(magic) != WNDR3700_MAGIC_LEN) { - fprintf(stderr, "Invalid magic: '%s'\n", magic); - exit(1); - } - - // mmap input_file - if ((fd = open(argv[1], O_RDONLY)) < 0 - || (len = lseek(fd, 0, SEEK_END)) < 0 - || (input_file = mmap(0, len, PROT_READ, MAP_SHARED, fd, 0)) == (void *) (-1) - || close(fd) < 0) - { - fprintf(stderr, "Error loading file %s: %s\n", argv[1], strerror(errno)); - exit(1); - } - - buflen = len; - - init_crc32(); - - // preload header - memcpy(&header, input_file, sizeof(header)); - - memcpy(header.magic, magic, WNDR3700_MAGIC_LEN); - header.crc = 0; - - // create a firmware image in memory and copy the input_file to it - buf = malloc(buflen); - memcpy(buf, input_file, len); - - // CRC of temporary header - header.crc = htonl(crc32buf((unsigned char*)&header, sizeof(header))); - - memcpy(buf, &header, sizeof(header)); - - // write the buf - if ((fd = open(argv[2], O_CREAT|O_WRONLY|O_TRUNC,0644)) < 0 - || write(fd, buf, buflen) != buflen - || close(fd) < 0) - { - fprintf(stderr, "Error storing file %s: %s\n", argv[2], strerror(errno)); - exit(2); - } - - free(buf); - - munmap(input_file,len); - - return 0; -} diff --git a/tools/firmware-utils/src/wrt400n.c b/tools/firmware-utils/src/wrt400n.c index a9a4908060c..1cf1debc893 100644 --- a/tools/firmware-utils/src/wrt400n.c +++ b/tools/firmware-utils/src/wrt400n.c @@ -7,12 +7,14 @@ * * Author: Sandeep Mistry */ +#include <arpa/inet.h> #include <fcntl.h> #include <stdio.h> #include <stdint.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> +#include <unistd.h> #include "cyg_crc.h" diff --git a/tools/firmware-utils/src/xorimage.c b/tools/firmware-utils/src/xorimage.c index b5ab83fa7a6..ca6e43742a1 100644 --- a/tools/firmware-utils/src/xorimage.c +++ b/tools/firmware-utils/src/xorimage.c @@ -21,7 +21,6 @@ #include <stdlib.h> #include <string.h> #include <stdint.h> -#include <time.h> #include <unistd.h> #include <sys/stat.h> diff --git a/tools/firmware-utils/src/zyimage.c b/tools/firmware-utils/src/zyimage.c new file mode 100644 index 00000000000..6aacf2ff1bd --- /dev/null +++ b/tools/firmware-utils/src/zyimage.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2014 Soul Trace <S-trace@list.ru> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#define _POSIX_SOURCE +#define _POSIX_C_SOURCE 199309L /* getopt */ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <unistd.h> + +#define szbuf 32768 + +u_int32_t crc_tab[256]; + +u_int32_t chksum_crc32 (FILE *f) +{ + register unsigned long crc; + unsigned long i, j; + char *buffer = malloc(szbuf); + char *buf; + + crc = 0xFFFFFFFF; + while (!feof(f)) + { + j = fread(buffer, 1, szbuf, f); + buf = buffer; + for (i = 0; i < j; i++) + crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *buf++) & 0xFF]; + } + free(buffer); + return crc; +} + +void chksum_crc32gentab () +{ + unsigned long crc, poly; + int i, j; + + poly = 0xEDB88320L; + for (i = 0; i < 256; i++) + { + crc = i; + for (j = 8; j > 0; j--) + { + if (crc & 1) + crc = (crc >> 1) ^ poly; + else + crc >>= 1; + } + crc_tab[i] = crc; + } +} + +void usage(char *progname) +{ + printf("Usage: %s [ -v Version ] [ -d Device_ID ] <input file>\n", progname); + exit(1); +} + +int main(int argc, char *argv[]) { + struct signature + { + const char magic[4]; + unsigned int device_id; + char firmware_version[48]; + unsigned int crc32; + } + sign = + { + { 'Z', 'N', 'B', 'G' }, + 1, + { "V.1.0.0(1.0.0)" }, + 0 + }; + FILE *f; + struct signature oldsign; + char *filename; + static const char *optString; + int opt; + + if (argc < 1) + usage(argv[0]); + + optString = "v:d:h"; + opt = getopt( argc, argv, optString ); + while( opt != -1 ) { + switch( opt ) { + case 'v': + if (optarg == NULL) + usage(argv[0]); + strncpy(sign.firmware_version, optarg, sizeof(sign.firmware_version)-1); + sign.firmware_version[sizeof(sign.firmware_version)-1]='\0'; /* Make sure that string is terminated correctly */ + break; + + case 'd': + sign.device_id = atoi(optarg); + if (sign.device_id == 0) + sign.device_id = (int)strtol(optarg, NULL, 16); + break; + + case '?': + case 'h': + usage(argv[0]); + break; + + default: + break; + } + + opt = getopt( argc, argv, optString ); + } + + chksum_crc32gentab(); + + filename=argv[optind]; + if (access(filename, W_OK) || access(filename, R_OK)) + { + printf("Not open input file %s\n", filename); + exit(1); + } + f = fopen(argv[optind], "r+"); + if (f != NULL) + { + fseek(f, sizeof(sign)*-1, SEEK_END); + fread(&oldsign, sizeof(oldsign), 1, f); + + if (strncmp(oldsign.magic,"ZNBG", sizeof(oldsign.magic)) == 0 ) + { + printf("Image is already signed as:\nDevice ID: 0x%08x\nFirmware version: %s\nImage CRC32: 0x%x\n", oldsign.device_id, oldsign.firmware_version, oldsign.crc32); + exit(0); + } + + fseek(f, 0, SEEK_SET); + sign.crc32 = chksum_crc32(f); + fwrite(&sign, sizeof(sign), 1, f); + fclose(f); + + printf("Image signed as:\nDevice ID: 0x%08x\nFirmware version: %s\nImage CRC32: 0x%x\n", sign.device_id, sign.firmware_version, sign.crc32); + } + return 0; +} diff --git a/tools/firmware-utils/src/zyxbcm.c b/tools/firmware-utils/src/zyxbcm.c new file mode 100644 index 00000000000..1a2926bfd31 --- /dev/null +++ b/tools/firmware-utils/src/zyxbcm.c @@ -0,0 +1,259 @@ +/* + * zyxbcm.c - based on Jonas Gorski's spw303v.c + * + * Copyright (C) 2014 Álvaro Fernández Rojas <noltari@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <arpa/inet.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <unistd.h> +#include <sys/stat.h> + +#define TAGVER_LEN 4 /* Length of Tag Version */ +#define SIG1_LEN 20 /* Company Signature 1 Length */ +#define SIG2_LEN 14 /* Company Signature 2 Lenght */ +#define BOARDID_LEN 16 /* Length of BoardId */ +#define ENDIANFLAG_LEN 2 /* Endian Flag Length */ +#define CHIPID_LEN 6 /* Chip Id Length */ +#define IMAGE_LEN 10 /* Length of Length Field */ +#define ADDRESS_LEN 12 /* Length of Address field */ +#define DUALFLAG_LEN 2 /* Dual Image flag Length */ +#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */ +#define RSASIG_LEN 20 /* Length of RSA Signature in tag */ +#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */ +#define ZYX_TAGINFO1_LEN 20 /* Length of vendor information field1 in tag */ +#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */ +#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */ +#define CRC_LEN 4 /* Length of CRC in bytes */ + +#define IMAGETAG_CRC_START 0xFFFFFFFF + +struct bcm_tag { + char tagVersion[TAGVER_LEN]; // 0-3: Version of the image tag + char sig_1[SIG1_LEN]; // 4-23: Company Line 1 + char sig_2[SIG2_LEN]; // 24-37: Company Line 2 + char chipid[CHIPID_LEN]; // 38-43: Chip this image is for + char boardid[BOARDID_LEN]; // 44-59: Board name + char big_endian[ENDIANFLAG_LEN]; // 60-61: Map endianness -- 1 BE 0 LE + char totalLength[IMAGE_LEN]; // 62-71: Total length of image + char cfeAddress[ADDRESS_LEN]; // 72-83: Address in memory of CFE + char cfeLength[IMAGE_LEN]; // 84-93: Size of CFE + char flashImageStart[ADDRESS_LEN]; // 94-105: Address in memory of image start (kernel for OpenWRT, rootfs for stock firmware) + char flashRootLength[IMAGE_LEN]; // 106-115: Size of rootfs for flashing + char kernelAddress[ADDRESS_LEN]; // 116-127: Address in memory of kernel + char kernelLength[IMAGE_LEN]; // 128-137: Size of kernel + char dualImage[DUALFLAG_LEN]; // 138-139: Unused at present + char inactiveFlag[INACTIVEFLAG_LEN]; // 140-141: Unused at present + char rsa_signature[RSASIG_LEN]; // 142-161: RSA Signature (unused at present; some vendors may use this) + char information1[TAGINFO1_LEN]; // 162-191: Compilation and related information (not generated/used by OpenWRT) + char flashLayoutVer[FLASHLAYOUTVER_LEN]; // 192-195: Version flash layout + char fskernelCRC[CRC_LEN]; // 196-199: kernel+rootfs CRC32 + char information2[TAGINFO2_LEN]; // 200-215: Unused at present except Alice Gate where is is information + char imageCRC[CRC_LEN]; // 216-219: CRC32 of image less imagetag (kernel for Alice Gate) + char rootfsCRC[CRC_LEN]; // 220-223: CRC32 of rootfs partition + char kernelCRC[CRC_LEN]; // 224-227: CRC32 of kernel partition + char imageSequence[4]; // 228-231: Image sequence number + char rootLength[4]; // 232-235: steal from reserved1 to keep the real root length so we can use in the flash map even after we have change the rootLength to 0 to satisfy devices that check CRC on every boot + char headerCRC[CRC_LEN]; // 236-239: CRC32 of header excluding tagVersion + char reserved2[16]; // 240-255: Unused at present +}; + +struct zyxbcm_tag { + char tagVersion[TAGVER_LEN]; // 0-3: Version of the image tag + char sig_1[SIG1_LEN]; // 4-23: Company Line 1 + char sig_2[SIG2_LEN]; // 24-37: Company Line 2 + char chipid[CHIPID_LEN]; // 38-43: Chip this image is for + char boardid[BOARDID_LEN]; // 44-59: Board name + char big_endian[ENDIANFLAG_LEN]; // 60-61: Map endianness -- 1 BE 0 LE + char totalLength[IMAGE_LEN]; // 62-71: Total length of image + char cfeAddress[ADDRESS_LEN]; // 72-83: Address in memory of CFE + char cfeLength[IMAGE_LEN]; // 84-93: Size of CFE + char flashImageStart[ADDRESS_LEN]; // 94-105: Address in memory of image start (kernel for OpenWRT, rootfs for stock firmware) + char flashRootLength[IMAGE_LEN]; // 106-115: Size of rootfs for flashing + char kernelAddress[ADDRESS_LEN]; // 116-127: Address in memory of kernel + char kernelLength[IMAGE_LEN]; // 128-137: Size of kernel + char dualImage[DUALFLAG_LEN]; // 138-139: Unused at present + char inactiveFlag[INACTIVEFLAG_LEN]; // 140-141: Unused at present + char rsa_signature[RSASIG_LEN]; // 142-161: RSA Signature (unused at present; some vendors may use this) + char information1[ZYX_TAGINFO1_LEN]; // 162-181: Compilation and related information (not generated/used by OpenWRT) + char flashImageEnd[ADDRESS_LEN]; // 182-193: Address in memory of image end + char fskernelCRC[CRC_LEN]; // 194-197: kernel+rootfs CRC32 + char reserved1[2]; // 198-199: Unused at present + char information2[TAGINFO2_LEN]; // 200-215: Unused at present except Alice Gate where is is information + char imageCRC[CRC_LEN]; // 216-219: CRC32 of image less imagetag (kernel for Alice Gate) + char rootfsCRC[CRC_LEN]; // 220-223: CRC32 of rootfs partition + char kernelCRC[CRC_LEN]; // 224-227: CRC32 of kernel partition + char imageSequence[4]; // 228-231: Image sequence number + char rootLength[4]; // 232-235: steal from reserved1 to keep the real root length so we can use in the flash map even after we have change the rootLength to 0 to satisfy devices that check CRC on every boot + char headerCRC[CRC_LEN]; // 236-239: CRC32 of header excluding tagVersion + char reserved2[16]; // 240-255: Unused at present +}; + +static uint32_t crc32tab[256] = { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + +uint32_t crc32(uint32_t crc, uint8_t *data, size_t len) +{ + while (len--) + crc = (crc >> 8) ^ crc32tab[(crc ^ *data++) & 0xFF]; + + return crc; +} + +void fix_header(void *buf) +{ + struct bcm_tag *bcmtag = buf; + struct zyxbcm_tag *zyxtag = buf; + uint8_t fskernel_crc[CRC_LEN]; + uint32_t crc; + uint64_t flash_start, rootfs_len, kernel_len; + + /* Backup values */ + flash_start = strtoul(bcmtag->flashImageStart, NULL, 10); + rootfs_len = strtoul(bcmtag->flashRootLength, NULL, 10); + kernel_len = strtoul(bcmtag->kernelLength, NULL, 10); + memcpy(fskernel_crc, bcmtag->fskernelCRC, CRC_LEN); + + /* Clear values */ + zyxtag->information1[ZYX_TAGINFO1_LEN - 1] = 0; + memset(zyxtag->flashImageEnd, 0, ADDRESS_LEN); + memset(zyxtag->fskernelCRC, 0, CRC_LEN); + memset(zyxtag->reserved1, 0, 2); + + /* Replace values */ + sprintf(zyxtag->flashImageEnd, "%lu", flash_start + rootfs_len + kernel_len); + memcpy(zyxtag->fskernelCRC, fskernel_crc, CRC_LEN); + + /* Update tag crc */ + crc = htonl(crc32(IMAGETAG_CRC_START, buf, 236)); + memcpy(zyxtag->headerCRC, &crc, 4); +} + +void usage(void) __attribute__ (( __noreturn__ )); + +void usage(void) +{ + fprintf(stderr, "Usage: zyxbcm [-i <inputfile>] [-o <outputfile>]\n"); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) +{ + char buf[1024]; /* keep this at 1k or adjust garbage calc below */ + FILE *in = stdin, *out = stdout; + char *ifn = NULL, *ofn = NULL; + size_t n; + int c, first_block = 1; + + while ((c = getopt(argc, argv, "i:o:h")) != -1) { + switch (c) { + case 'i': + ifn = optarg; + break; + case 'o': + ofn = optarg; + break; + case 'h': + default: + usage(); + } + } + + if (optind != argc || optind == 1) { + fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); + usage(); + } + + if (ifn && !(in = fopen(ifn, "r"))) { + fprintf(stderr, "can not open \"%s\" for reading\n", ifn); + usage(); + } + + if (ofn && !(out = fopen(ofn, "w"))) { + fprintf(stderr, "can not open \"%s\" for writing\n", ofn); + usage(); + } + + while ((n = fread(buf, 1, sizeof(buf), in)) > 0) { + if (n < sizeof(buf)) { + if (ferror(in)) { + FREAD_ERROR: + fprintf(stderr, "fread error\n"); + return EXIT_FAILURE; + } + } + + if (first_block && n >= 256) { + fix_header(buf); + first_block = 0; + } + + if (!fwrite(buf, n, 1, out)) { + FWRITE_ERROR: + fprintf(stderr, "fwrite error\n"); + return EXIT_FAILURE; + } + } + + if (ferror(in)) { + goto FREAD_ERROR; + } + + if (fflush(out)) { + goto FWRITE_ERROR; + } + + fclose(in); + fclose(out); + + return EXIT_SUCCESS; +} diff --git a/tools/flex/Makefile b/tools/flex/Makefile index 2fcc2c643fd..1eff81f3451 100644 --- a/tools/flex/Makefile +++ b/tools/flex/Makefile @@ -1,5 +1,5 @@ -# -# Copyright (C) 2008 OpenWrt.org +# +# Copyright (C) 2008-2016 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,15 +7,20 @@ include $(TOPDIR)/rules.mk PKG_NAME:=flex -PKG_VERSION:=2.5.35 +PKG_CPE_ID:=cpe:/a:flex_project:flex +PKG_VERSION:=2.6.4 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://github.com/westes/flex/releases/download/v$(PKG_VERSION)/ +PKG_HASH:=e87aae032bf07c26f85ac0ed3250998c37621d95f8bd748b31f15b33c45ee995 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 -PKG_SOURCE_URL:=@SF/$(PKG_NAME) -PKG_MD5SUM:=10714e50cea54dc7a227e3eddcd44d57 -PKG_CAT:=bzcat +HOST_FIXUP:=autoreconf +HOST_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/host-build.mk +HOST_CONFIGURE_ARGS += --disable-shared + define Host/Clean -$(MAKE) -C $(HOST_BUILD_DIR) uninstall $(call Host/Clean/Default) diff --git a/tools/flex/patches/100-disable-tests-docs.patch b/tools/flex/patches/100-disable-tests-docs.patch new file mode 100644 index 00000000000..f7097f2127d --- /dev/null +++ b/tools/flex/patches/100-disable-tests-docs.patch @@ -0,0 +1,13 @@ +--- a/Makefile.am ++++ b/Makefile.am +@@ -43,10 +43,7 @@ EXTRA_DIST = \ + + SUBDIRS = \ + src \ +- doc \ +- examples \ + po \ +- tests \ + tools + + # Create the ChangeLog, but only if we're inside a git working directory diff --git a/tools/flex/patches/200-build-AC_USE_SYSTEM_EXTENSIONS-in-configure.ac.patch b/tools/flex/patches/200-build-AC_USE_SYSTEM_EXTENSIONS-in-configure.ac.patch new file mode 100644 index 00000000000..7c3645c4747 --- /dev/null +++ b/tools/flex/patches/200-build-AC_USE_SYSTEM_EXTENSIONS-in-configure.ac.patch @@ -0,0 +1,27 @@ +From 24fd0551333e7eded87b64dd36062da3df2f6380 Mon Sep 17 00:00:00 2001 +From: Explorer09 <explorer09@gmail.com> +Date: Mon, 4 Sep 2017 10:47:33 +0800 +Subject: [PATCH] build: AC_USE_SYSTEM_EXTENSIONS in configure.ac. + +This would, e.g. define _GNU_SOURCE in config.h, enabling the +reallocarray() prototype in glibc 2.26+ on Linux systems with that +version of glibc. + +Fixes #241. +--- + configure.ac | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/configure.ac ++++ b/configure.ac +@@ -25,8 +25,10 @@ + # autoconf requirements and initialization + + AC_INIT([the fast lexical analyser generator],[2.6.4],[flex-help@lists.sourceforge.net],[flex]) ++AC_PREREQ([2.60]) + AC_CONFIG_SRCDIR([src/scan.l]) + AC_CONFIG_AUX_DIR([build-aux]) ++AC_USE_SYSTEM_EXTENSIONS + LT_INIT + AM_INIT_AUTOMAKE([1.11.3 -Wno-portability foreign check-news std-options dist-lzip parallel-tests subdir-objects]) + AC_CONFIG_HEADER([src/config.h]) diff --git a/tools/flock/Makefile b/tools/flock/Makefile index 64a8655b831..9939d121169 100644 --- a/tools/flock/Makefile +++ b/tools/flock/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006-2008 OpenWrt.org +# Copyright (C) 2006-2012 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -10,6 +10,9 @@ PKG_NAME := flock include $(INCLUDE_DIR)/host-build.mk +HOSTCC := $(HOSTCC_NOCACHE) +HOSTCXX := $(HOSTCXX_NOCACHE) + define Host/Compile mkdir -p $(HOST_BUILD_DIR) $(HOSTCC) $(HOST_CFLAGS) -o $(HOST_BUILD_DIR)/flock src/flock.c diff --git a/tools/flock/src/flock.c b/tools/flock/src/flock.c index 13baec46ca4..37ab0ea72da 100644 --- a/tools/flock/src/flock.c +++ b/tools/flock/src/flock.c @@ -39,6 +39,7 @@ #include <sys/file.h> #include <sys/time.h> #include <sys/wait.h> +#include <fcntl.h> #define PACKAGE_STRING "util-linux-ng 2.18" #define _(x) (x) @@ -132,6 +133,7 @@ int main(int argc, char *argv[]) int do_close = 0; int err; int status; + int open_flags = 0; char *eon; char **cmd_argv = NULL, *sh_c_argv[4]; const char *filename = NULL; @@ -265,6 +267,21 @@ int main(int argc, char *argv[]) if ( timeout_expired ) exit(1); /* -w option set and failed to lock */ continue; /* otherwise try again */ + case EBADF: /* since Linux 3.4 (commit 55725513) */ + /* Probably NFSv4 where flock() is emulated by fcntl(). + * Let's try to reopen in read-write mode. + */ + if (!(open_flags & O_RDWR) && + type != LOCK_SH && + filename && + access(filename, R_OK | W_OK) == 0) { + + close(fd); + open_flags = O_RDWR; + fd = open(filename, open_flags); + break; + } + /* go through */ default: /* Other errors */ if ( filename ) fprintf(stderr, "%s: %s: %s\n", program, filename, strerror(err)); diff --git a/tools/genext2fs/Makefile b/tools/genext2fs/Makefile index 1f69b2a6b6f..3a911df91a4 100644 --- a/tools/genext2fs/Makefile +++ b/tools/genext2fs/Makefile @@ -12,7 +12,7 @@ PKG_VERSION:=1.4.1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@SF/genext2fs -PKG_MD5SUM:=b7b6361bcce2cedff1ae437fadafe53b +PKG_HASH:=404dbbfa7a86a6c3de8225c8da254d026b17fd288e05cec4df2cc7e1f4feecfc include $(INCLUDE_DIR)/host-build.mk @@ -36,6 +36,7 @@ HOST_CONFIGURE_ARGS = \ define Host/Compile $(MAKE) -C $(HOST_BUILD_DIR) \ CFLAGS="$(HOST_CFLAGS)" \ + LDFLAGS="$(HOST_LDFLAGS)" \ all endef diff --git a/tools/genext2fs/patches/100-c99_scanf.patch b/tools/genext2fs/patches/100-c99_scanf.patch new file mode 100644 index 00000000000..e7aa17cc6fa --- /dev/null +++ b/tools/genext2fs/patches/100-c99_scanf.patch @@ -0,0 +1,21 @@ +commit 3b8ca0ce9a0b58287a780747c90c449bdebfe464 +Author: Xavier Bestel <bestouff@users.sourceforge.net> +Date: Mon Jan 14 08:52:44 2008 +0000 + + removed use of %as is scanf (GNU conflicts with C99) by Giacomo Catenazzi <cate@debian.org> + +diff --git a/genext2fs.c b/genext2fs.c +index 070b270..f0d797d 100644 +--- a/genext2fs.c ++++ b/genext2fs.c +@@ -286,7 +286,9 @@ typedef unsigned int uint32; + // older solaris. Note that this is still not very portable, in that + // the return value cannot be trusted. + +-#if SCANF_CAN_MALLOC ++#if 0 // SCANF_CAN_MALLOC ++// C99 define "a" for floating point, so you can have runtime surprise ++// according the library versions + # define SCANF_PREFIX "a" + # define SCANF_STRING(s) (&s) + #else diff --git a/tools/genext2fs/patches/200-autoconf.patch b/tools/genext2fs/patches/200-autoconf.patch new file mode 100644 index 00000000000..b3317bdd10a --- /dev/null +++ b/tools/genext2fs/patches/200-autoconf.patch @@ -0,0 +1,13 @@ +Index: genext2fs/m4/ac_func_scanf_can_malloc.m4 +=================================================================== +--- genext2fs.orig/m4/ac_func_scanf_can_malloc.m4 2011-09-03 21:28:49.000000000 +0200 ++++ genext2fs/m4/ac_func_scanf_can_malloc.m4 2011-09-03 21:29:41.000000000 +0200 +@@ -9,7 +9,7 @@ + # -------------------------------------- + AC_DEFUN([AC_FUNC_SCANF_CAN_MALLOC], + [ AC_CHECK_HEADERS([stdlib.h]) +- AC_CACHE_CHECK([whether scanf can malloc], [ac_scanf_can_malloc], ++ AC_CACHE_CHECK([whether scanf can malloc], [ac_cv_func_scanf_can_malloc], + [ AC_RUN_IFELSE( + [ AC_LANG_PROGRAM( + [ diff --git a/tools/genext2fs/patches/300-blocksize-creator.patch b/tools/genext2fs/patches/300-blocksize-creator.patch new file mode 100644 index 00000000000..97a4836eeb2 --- /dev/null +++ b/tools/genext2fs/patches/300-blocksize-creator.patch @@ -0,0 +1,558 @@ +Index: genext2fs/genext2fs.c +=================================================================== +--- genext2fs.orig/genext2fs.c 2011-09-03 14:21:17.000000000 +0200 ++++ genext2fs/genext2fs.c 2011-09-03 14:21:17.000000000 +0200 +@@ -151,13 +151,24 @@ + + // block size + +-#define BLOCKSIZE 1024 ++static int blocksize = 1024; ++ ++#define BLOCKSIZE blocksize + #define BLOCKS_PER_GROUP 8192 + #define INODES_PER_GROUP 8192 + /* Percentage of blocks that are reserved.*/ + #define RESERVED_BLOCKS 5/100 + #define MAX_RESERVED_BLOCKS 25/100 + ++/* The default value for s_creator_os. */ ++#if defined(__GNU__) ++# define CREATOR_OS 1 /* Hurd */ ++#elif defined(__FreeBSD__) ++# define CREATOR_OS 3 /* FreeBSD */ ++#else ++# define CREATOR_OS 0 /* Linux */ ++#endif ++ + + // inode block size (why is it != BLOCKSIZE ?!?) + /* The field i_blocks in the ext2 inode stores the number of data blocks +@@ -239,10 +250,10 @@ + (fs)->sb.s_blocks_per_group - 1) / (fs)->sb.s_blocks_per_group) + + // Get group block bitmap (bbm) given the group number +-#define GRP_GET_GROUP_BBM(fs,grp) ( get_blk((fs),(fs)->gd[(grp)].bg_block_bitmap) ) ++#define GRP_GET_GROUP_BBM(fs,grp) ( get_blk((fs), get_gd((fs),(grp))->bg_block_bitmap) ) + + // Get group inode bitmap (ibm) given the group number +-#define GRP_GET_GROUP_IBM(fs,grp) ( get_blk((fs),(fs)->gd[(grp)].bg_inode_bitmap) ) ++#define GRP_GET_GROUP_IBM(fs,grp) ( get_blk((fs), get_gd((fs),(grp))->bg_inode_bitmap) ) + + // Given an inode number find the group it belongs to + #define GRP_GROUP_OF_INODE(fs,nod) ( ((nod)-1) / (fs)->sb.s_inodes_per_group) +@@ -532,7 +543,7 @@ + char d_name[0]; + } directory; + +-typedef uint8 block[BLOCKSIZE]; ++typedef uint8 *block; + + /* blockwalker fields: + The blockwalker is used to access all the blocks of a file (including +@@ -571,16 +582,12 @@ + + + /* Filesystem structure that support groups */ +-#if BLOCKSIZE == 1024 + typedef struct + { +- block zero; // The famous block 0 +- superblock sb; // The superblock +- groupdescriptor gd[0]; // The group descriptors ++ uint8 zero[1024]; // Room for bootloader stuff ++ superblock sb; // The superblock, always at 1024 ++ // group descriptors come next, see get_gd() below + } filesystem; +-#else +-#error UNHANDLED BLOCKSIZE +-#endif + + // now the endianness swap + +@@ -820,6 +827,14 @@ + return (uint8*)fs + blk*BLOCKSIZE; + } + ++// the group descriptors are aligned on the block size ++static inline groupdescriptor * ++get_gd(filesystem *fs, int no) ++{ ++ int gdblk = (sizeof (filesystem) + BLOCKSIZE - 1) / BLOCKSIZE; ++ return ((groupdescriptor *) get_blk(fs, gdblk)) + no; ++} ++ + // return a given inode from a filesystem + static inline inode * + get_nod(filesystem *fs, uint32 nod) +@@ -829,7 +844,7 @@ + + offset = GRP_IBM_OFFSET(fs,nod); + grp = GRP_GROUP_OF_INODE(fs,nod); +- itab = (inode *)get_blk(fs, fs->gd[grp].bg_inode_table); ++ itab = (inode *)get_blk(fs, get_gd(fs,grp)->bg_inode_table); + return itab+offset-1; + } + +@@ -875,18 +890,18 @@ + + grp = GRP_GROUP_OF_INODE(fs,nod); + nbgroups = GRP_NBGROUPS(fs); +- if(!(bk = allocate(get_blk(fs,fs->gd[grp].bg_block_bitmap), 0))) { ++ if(!(bk = allocate(GRP_GET_GROUP_BBM(fs, grp), 0))) { + for(grp=0;grp<nbgroups && !bk;grp++) +- bk=allocate(get_blk(fs,fs->gd[grp].bg_block_bitmap),0); ++ bk = allocate(GRP_GET_GROUP_BBM(fs, grp), 0); + grp--; + } + if (!bk) + error_msg_and_die("couldn't allocate a block (no free space)"); +- if(!(fs->gd[grp].bg_free_blocks_count--)) ++ if(!(get_gd(fs, grp)->bg_free_blocks_count--)) + error_msg_and_die("group descr %d. free blocks count == 0 (corrupted fs?)",grp); + if(!(fs->sb.s_free_blocks_count--)) + error_msg_and_die("superblock free blocks count == 0 (corrupted fs?)"); +- return fs->sb.s_blocks_per_group*grp + bk; ++ return fs->sb.s_first_data_block + fs->sb.s_blocks_per_group*grp + (bk-1); + } + + // free a block +@@ -897,8 +912,8 @@ + + grp = bk / fs->sb.s_blocks_per_group; + bk %= fs->sb.s_blocks_per_group; +- deallocate(get_blk(fs,fs->gd[grp].bg_block_bitmap), bk); +- fs->gd[grp].bg_free_blocks_count++; ++ deallocate(GRP_GET_GROUP_BBM(fs, grp), bk); ++ get_gd(fs, grp)->bg_free_blocks_count++; + fs->sb.s_free_blocks_count++; + } + +@@ -918,16 +933,16 @@ + /* We do it for all inodes. */ + avefreei = fs->sb.s_free_inodes_count / nbgroups; + for(grp=0; grp<nbgroups; grp++) { +- if (fs->gd[grp].bg_free_inodes_count < avefreei || +- fs->gd[grp].bg_free_inodes_count == 0) ++ if (get_gd(fs, grp)->bg_free_inodes_count < avefreei || ++ get_gd(fs, grp)->bg_free_inodes_count == 0) + continue; + if (!best_group || +- fs->gd[grp].bg_free_blocks_count > fs->gd[best_group].bg_free_blocks_count) ++ get_gd(fs, grp)->bg_free_blocks_count > get_gd(fs, best_group)->bg_free_blocks_count) + best_group = grp; + } +- if (!(nod = allocate(get_blk(fs,fs->gd[best_group].bg_inode_bitmap),0))) ++ if (!(nod = allocate(GRP_GET_GROUP_IBM(fs, best_group), 0))) + error_msg_and_die("couldn't allocate an inode (no free inode)"); +- if(!(fs->gd[best_group].bg_free_inodes_count--)) ++ if(!(get_gd(fs, best_group)->bg_free_inodes_count--)) + error_msg_and_die("group descr. free blocks count == 0 (corrupted fs?)"); + if(!(fs->sb.s_free_inodes_count--)) + error_msg_and_die("superblock free blocks count == 0 (corrupted fs?)"); +@@ -1390,7 +1405,7 @@ + case FM_IFDIR: + add2dir(fs, nod, nod, "."); + add2dir(fs, nod, parent_nod, ".."); +- fs->gd[GRP_GROUP_OF_INODE(fs,nod)].bg_used_dirs_count++; ++ get_gd(fs, GRP_GROUP_OF_INODE(fs,nod))->bg_used_dirs_count++; + break; + } + } +@@ -1860,7 +1875,7 @@ + swap_nod(nod); + } + for(i=0;i<GRP_NBGROUPS(fs);i++) +- swap_gd(&(fs->gd[i])); ++ swap_gd(get_gd(fs, i)); + swap_sb(&fs->sb); + } + +@@ -1870,7 +1885,7 @@ + uint32 i; + swap_sb(&fs->sb); + for(i=0;i<GRP_NBGROUPS(fs);i++) +- swap_gd(&(fs->gd[i])); ++ swap_gd(get_gd(fs, i)); + for(i = 1; i < fs->sb.s_inodes_count; i++) + { + inode *nod = get_nod(fs, i); +@@ -1895,7 +1910,8 @@ + + // initialize an empty filesystem + static filesystem * +-init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp) ++init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, ++ uint32 fs_timestamp, uint32 creator_os) + { + uint32 i; + filesystem *fs; +@@ -1921,10 +1937,14 @@ + */ + min_nbgroups = (nbinodes + INODES_PER_GROUP - 1) / INODES_PER_GROUP; + ++ /* On filesystems with 1k block size, the bootloader area uses a full ++ * block. For 2048 and up, the superblock can be fitted into block 0. ++ */ ++ first_block = (BLOCKSIZE == 1024); ++ + /* nbblocks is the total number of blocks in the filesystem. + * a block group can have no more than 8192 blocks. + */ +- first_block = (BLOCKSIZE == 1024); + nbgroups = (nbblocks - first_block + BLOCKS_PER_GROUP - 1) / BLOCKS_PER_GROUP; + if(nbgroups < min_nbgroups) nbgroups = min_nbgroups; + nbblocks_per_group = rndup((nbblocks - first_block + nbgroups - 1)/nbgroups, 8); +@@ -1936,10 +1956,10 @@ + gdsz = rndup(nbgroups*sizeof(groupdescriptor),BLOCKSIZE)/BLOCKSIZE; + itblsz = nbinodes_per_group * sizeof(inode)/BLOCKSIZE; + overhead_per_group = 3 /*sb,bbm,ibm*/ + gdsz + itblsz; +- if((uint32)nbblocks - 1 < overhead_per_group * nbgroups) +- error_msg_and_die("too much overhead, try fewer inodes or more blocks. Note: options have changed, see --help or the man page."); +- free_blocks = nbblocks - overhead_per_group*nbgroups - 1 /*boot block*/; ++ free_blocks = nbblocks - overhead_per_group*nbgroups - first_block; + free_blocks_per_group = nbblocks_per_group - overhead_per_group; ++ if(free_blocks < 0) ++ error_msg_and_die("too much overhead, try fewer inodes or more blocks. Note: options have changed, see --help or the man page."); + + if(!(fs = (filesystem*)calloc(nbblocks, BLOCKSIZE))) + error_msg_and_die("not enough memory for filesystem"); +@@ -1959,28 +1979,31 @@ + fs->sb.s_wtime = fs_timestamp; + fs->sb.s_magic = EXT2_MAGIC_NUMBER; + fs->sb.s_lastcheck = fs_timestamp; ++ fs->sb.s_creator_os = creator_os; + + // set up groupdescriptors +- for(i=0, bbmpos=gdsz+2, ibmpos=bbmpos+1, itblpos=ibmpos+1; ++ for(i=0, bbmpos=first_block+1+gdsz, ibmpos=bbmpos+1, itblpos=ibmpos+1; + i<nbgroups; + i++, bbmpos+=nbblocks_per_group, ibmpos+=nbblocks_per_group, itblpos+=nbblocks_per_group) + { ++ groupdescriptor *gd = get_gd(fs, i); ++ + if(free_blocks > free_blocks_per_group) { +- fs->gd[i].bg_free_blocks_count = free_blocks_per_group; ++ gd->bg_free_blocks_count = free_blocks_per_group; + free_blocks -= free_blocks_per_group; + } else { +- fs->gd[i].bg_free_blocks_count = free_blocks; ++ gd->bg_free_blocks_count = free_blocks; + free_blocks = 0; // this is the last block group + } + if(i) +- fs->gd[i].bg_free_inodes_count = nbinodes_per_group; ++ gd->bg_free_inodes_count = nbinodes_per_group; + else +- fs->gd[i].bg_free_inodes_count = nbinodes_per_group - ++ gd->bg_free_inodes_count = nbinodes_per_group - + EXT2_FIRST_INO + 2; +- fs->gd[i].bg_used_dirs_count = 0; +- fs->gd[i].bg_block_bitmap = bbmpos; +- fs->gd[i].bg_inode_bitmap = ibmpos; +- fs->gd[i].bg_inode_table = itblpos; ++ gd->bg_used_dirs_count = 0; ++ gd->bg_block_bitmap = bbmpos; ++ gd->bg_inode_bitmap = ibmpos; ++ gd->bg_inode_table = itblpos; + } + + /* Mark non-filesystem blocks and inodes as allocated */ +@@ -1988,9 +2011,9 @@ + for(i = 0; i<nbgroups;i++) { + + /* Block bitmap */ +- bbm = get_blk(fs,fs->gd[i].bg_block_bitmap); ++ bbm = GRP_GET_GROUP_BBM(fs, i); + //non-filesystem blocks +- for(j = fs->gd[i].bg_free_blocks_count ++ for(j = get_gd(fs, i)->bg_free_blocks_count + + overhead_per_group + 1; j <= BLOCKSIZE * 8; j++) + allocate(bbm, j); + //system blocks +@@ -1998,7 +2021,7 @@ + allocate(bbm, j); + + /* Inode bitmap */ +- ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap); ++ ibm = GRP_GET_GROUP_IBM(fs, i); + //non-filesystem inodes + for(j = fs->sb.s_inodes_per_group+1; j <= BLOCKSIZE * 8; j++) + allocate(ibm, j); +@@ -2012,9 +2035,9 @@ + // make root inode and directory + /* We have groups now. Add the root filesystem in group 0 */ + /* Also increment the directory count for group 0 */ +- fs->gd[0].bg_free_inodes_count--; +- fs->gd[0].bg_used_dirs_count = 1; +- itab0 = (inode *)get_blk(fs,fs->gd[0].bg_inode_table); ++ get_gd(fs, 0)->bg_free_inodes_count--; ++ get_gd(fs, 0)->bg_used_dirs_count = 1; ++ itab0 = (inode *)get_blk(fs, get_gd(fs,0)->bg_inode_table); + itab0[EXT2_ROOT_INO-1].i_mode = FM_IFDIR | FM_IRWXU | FM_IRGRP | FM_IROTH | FM_IXGRP | FM_IXOTH; + itab0[EXT2_ROOT_INO-1].i_ctime = fs_timestamp; + itab0[EXT2_ROOT_INO-1].i_mtime = fs_timestamp; +@@ -2338,8 +2361,9 @@ + for (i = 0; i < GRP_NBGROUPS(fs); i++) { + printf("Group No: %d\n", i+1); + printf("block bitmap: block %d,inode bitmap: block %d, inode table: block %d\n", +- fs->gd[i].bg_block_bitmap, fs->gd[i].bg_inode_bitmap, +- fs->gd[i].bg_inode_table); ++ get_gd(fs, i)->bg_block_bitmap, ++ get_gd(fs, i)->bg_inode_bitmap, ++ get_gd(fs, i)->bg_inode_table); + printf("block bitmap allocation:\n"); + print_bm(GRP_GET_GROUP_BBM(fs, i),fs->sb.s_blocks_per_group); + printf("inode bitmap allocation:\n"); +@@ -2421,10 +2445,12 @@ + " -x, --starting-image <image>\n" + " -d, --root <directory>\n" + " -D, --devtable <file>\n" ++ " -B, --block-size <bytes>\n" + " -b, --size-in-blocks <blocks>\n" + " -i, --bytes-per-inode <bytes per inode>\n" + " -N, --number-of-inodes <number of inodes>\n" + " -m, --reserved-percentage <percentage of blocks to reserve>\n" ++ " -o, --creator-os <os> 'linux', 'hurd', 'freebsd' or a numerical value.\n" + " -g, --block-map <path> Generate a block map file for this path.\n" + " -e, --fill-value <value> Fill unallocated blocks with value.\n" + " -z, --allow-holes Allow files with holes.\n" +@@ -2446,6 +2472,29 @@ + extern char* optarg; + extern int optind, opterr, optopt; + ++// parse the value for -o <os> ++int ++lookup_creator_os(const char *name) ++{ ++ static const char *const creators[] = ++ {"linux", "hurd", "2", "freebsd", NULL}; ++ char *endptr; ++ int i; ++ ++ // numerical value ? ++ i = strtol(name, &endptr, 0); ++ if(name[0] && *endptr == '\0') ++ return i; ++ ++ // symbolic name ? ++ for(i=0; creators[i]; i++) ++ if(strcasecmp(creators[i], name) == 0) ++ return i; ++ ++ // whatever ? ++ return -1; ++} ++ + int + main(int argc, char **argv) + { +@@ -2455,6 +2504,7 @@ + float bytes_per_inode = -1; + float reserved_frac = -1; + int fs_timestamp = -1; ++ int creator_os = CREATOR_OS; + char * fsout = "-"; + char * fsin = 0; + char * dopt[MAX_DOPT]; +@@ -2478,10 +2528,12 @@ + { "starting-image", required_argument, NULL, 'x' }, + { "root", required_argument, NULL, 'd' }, + { "devtable", required_argument, NULL, 'D' }, ++ { "block-size", required_argument, NULL, 'B' }, + { "size-in-blocks", required_argument, NULL, 'b' }, + { "bytes-per-inode", required_argument, NULL, 'i' }, + { "number-of-inodes", required_argument, NULL, 'N' }, + { "reserved-percentage", required_argument, NULL, 'm' }, ++ { "creator-os", required_argument, NULL, 'o' }, + { "block-map", required_argument, NULL, 'g' }, + { "fill-value", required_argument, NULL, 'e' }, + { "allow-holes", no_argument, NULL, 'z' }, +@@ -2497,11 +2549,11 @@ + + app_name = argv[0]; + +- while((c = getopt_long(argc, argv, "x:d:D:b:i:N:m:g:e:zfqUPhVv", longopts, NULL)) != EOF) { ++ while((c = getopt_long(argc, argv, "x:d:D:B:b:i:N:m:o:g:e:zfqUPhVv", longopts, NULL)) != EOF) { + #else + app_name = argv[0]; + +- while((c = getopt(argc, argv, "x:d:D:b:i:N:m:g:e:zfqUPhVv")) != EOF) { ++ while((c = getopt(argc, argv, "x:d:D:B:b:i:N:m:o:g:e:zfqUPhVv")) != EOF) { + #endif /* HAVE_GETOPT_LONG */ + switch(c) + { +@@ -2512,6 +2564,9 @@ + case 'D': + dopt[didx++] = optarg; + break; ++ case 'B': ++ blocksize = SI_atof(optarg); ++ break; + case 'b': + nbblocks = SI_atof(optarg); + break; +@@ -2524,6 +2579,9 @@ + case 'm': + reserved_frac = SI_atof(optarg) / 100; + break; ++ case 'o': ++ creator_os = lookup_creator_os(optarg); ++ break; + case 'g': + gopt[gidx++] = optarg; + break; +@@ -2567,6 +2625,11 @@ + error_msg_and_die("Not enough arguments. Try --help or else see the man page."); + fsout = argv[optind]; + ++ if(blocksize != 1024 && blocksize != 2048 && blocksize != 4096) ++ error_msg_and_die("Valid block sizes: 1024, 2048 or 4096."); ++ if(creator_os < 0) ++ error_msg_and_die("Creator OS unknown."); ++ + hdlinks.hdl = (struct hdlink_s *)malloc(hdlink_cnt * sizeof(struct hdlink_s)); + if (!hdlinks.hdl) + error_msg_and_die("Not enough memory"); +@@ -2611,7 +2674,8 @@ + } + if(fs_timestamp == -1) + fs_timestamp = time(NULL); +- fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp); ++ fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, ++ fs_timestamp, creator_os); + } + + populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL); +Index: genext2fs/test-gen.lib +=================================================================== +--- genext2fs.orig/test-gen.lib 2011-09-03 13:40:35.000000000 +0200 ++++ genext2fs/test-gen.lib 2011-09-03 14:21:17.000000000 +0200 +@@ -8,7 +8,7 @@ + # Creates an image with a file of given size + # Usage: dgen file-size number-of-blocks + dgen () { +- size=$1; blocks=$2 ++ size=$1; blocks=$2; blocksz=$3; + rm -rf test + mkdir -p test + cd test +@@ -20,7 +20,7 @@ + chmod 777 file.$1 + TZ=UTC-11 touch -t 200502070321.43 file.$1 . + cd .. +- ./genext2fs -N 17 -b $blocks -d test -f -q ext2.img ++ ./genext2fs -B $blocksz -N 17 -b $blocks -d test -f -o Linux -q ext2.img + } + + # fgen - Exercises the -f spec-file option of genext2fs +@@ -31,7 +31,7 @@ + mkdir -p test + cp $fname test + TZ=UTC-11 touch -t 200502070321.43 test/$fname +- ./genext2fs -N 92 -b $blocks -D test/$fname -f ext2.img ++ ./genext2fs -N 92 -b $blocks -D test/$fname -f -o Linux ext2.img + } + + # gen_cleanup - Remove the files generated by the above functions +Index: genext2fs/test-mount.sh +=================================================================== +--- genext2fs.orig/test-mount.sh 2011-09-03 13:40:35.000000000 +0200 ++++ genext2fs/test-mount.sh 2011-09-03 14:21:17.000000000 +0200 +@@ -33,9 +33,9 @@ + # and returns the command line with which to invoke dtest() + # Usage: dtest-mount file-size number-of-blocks + dtest_mount () { +- size=$1; blocks=$2 +- echo Testing with file of size $size +- dgen $size $blocks ++ size=$1; blocks=$2; blocksz=$3; ++ echo Testing $blocks blocks of $blocksz bytes with file of size $size ++ dgen $size $blocks $blocksz + /sbin/e2fsck -fn ext2.img || fail + mkdir -p mnt + mount -t ext2 -o ro,loop ext2.img mnt || fail +@@ -44,7 +44,7 @@ + awk '{print $5}'`" ] ; then + fail + fi +- pass dtest $size $blocks ++ pass dtest $size $blocks $blocksz + } + + # ftest-mount - Exercise the -f spec-file option of genext2fs +@@ -75,13 +75,21 @@ + pass ftest $fname $blocks + } + +-dtest_mount 0 4096 +-dtest_mount 0 8193 +-dtest_mount 0 8194 +-dtest_mount 1 4096 +-dtest_mount 12288 4096 +-dtest_mount 274432 4096 +-dtest_mount 8388608 9000 +-dtest_mount 16777216 20000 ++dtest_mount 0 4096 1024 ++dtest_mount 0 2048 2048 ++dtest_mount 0 1024 4096 ++dtest_mount 0 8193 1024 ++dtest_mount 0 8194 1024 ++dtest_mount 0 8193 4096 ++dtest_mount 0 8194 2048 ++dtest_mount 1 4096 1024 ++dtest_mount 1 1024 4096 ++dtest_mount 12288 4096 1024 ++dtest_mount 274432 4096 1024 ++dtest_mount 8388608 9000 1024 ++dtest_mount 8388608 4500 2048 ++dtest_mount 8388608 2250 4096 ++dtest_mount 16777216 20000 1024 ++dtest_mount 16777216 10000 2048 + + ftest_mount device_table.txt 4096 +Index: genext2fs/test.sh +=================================================================== +--- genext2fs.orig/test.sh 2011-09-03 13:40:35.000000000 +0200 ++++ genext2fs/test.sh 2011-09-03 14:21:17.000000000 +0200 +@@ -30,9 +30,9 @@ + # Creates an image with a file of given size and verifies it + # Usage: dtest file-size number-of-blocks correct-checksum + dtest () { +- size=$1; blocks=$2; checksum=$3 ++ size=$1; blocks=$2; blocksz=$3; checksum=$4 + echo Testing with file of size $size +- dgen $size $blocks ++ dgen $size $blocks $blocksz + md5cmp $checksum + gen_cleanup + } +@@ -53,12 +53,20 @@ + # replace the following lines with the output of + # sudo sh test-mount.sh|grep test + +-dtest 0 4096 3bc6424b8fcd51a0de34ee59d91d5f16 +-dtest 0 8193 f174804f6b433b552706cbbfc60c416d +-dtest 0 8194 4855a55d0cbdc44584634df49ebd5711 +-dtest 1 4096 09c569b6bfb45222c729c42d04d5451f +-dtest 12288 4096 61febcbfbf32024ef99103fcdc282c39 +-dtest 274432 4096 0c517803552c55c1806e4220b0a0164f +-dtest 8388608 9000 e0e5ea15bced10ab486d8135584b5d8e +-dtest 16777216 20000 fdf636eb905ab4dc1bf76dce5ac5d209 ++dtest 0 4096 1024 3bc6424b8fcd51a0de34ee59d91d5f16 ++dtest 0 2048 2048 230afa16496df019878cc2370c661cdc ++dtest 0 1024 4096 ebff5eeb38b70f3f1cd081e60eb44561 ++dtest 0 8193 1024 f174804f6b433b552706cbbfc60c416d ++dtest 0 8194 1024 4855a55d0cbdc44584634df49ebd5711 ++dtest 0 8193 4096 c493679698418ec7e6552005e2d2a6d8 ++dtest 0 8194 2048 ec13f328fa7543563f35f494bddc059c ++dtest 1 4096 1024 09c569b6bfb45222c729c42d04d5451f ++dtest 1 1024 4096 d318a326fdc907810ae9e6b0a20e9b06 ++dtest 12288 4096 1024 61febcbfbf32024ef99103fcdc282c39 ++dtest 274432 4096 1024 0c517803552c55c1806e4220b0a0164f ++dtest 8388608 9000 1024 e0e5ea15bced10ab486d8135584b5d8e ++dtest 8388608 4500 2048 39f4d537a72f5053fd6891721c59680d ++dtest 8388608 2250 4096 1d697fa4bc2cfffe02ac91edfadc40bf ++dtest 16777216 20000 1024 fdf636eb905ab4dc1bf76dce5ac5d209 ++dtest 16777216 10000 2048 f9824a81ea5e74fdf469c097927c292b + ftest device_table.txt 4096 a0af06d944b11d2902dfd705484c64cc diff --git a/tools/genext2fs/patches/400-byteswap_fix.patch b/tools/genext2fs/patches/400-byteswap_fix.patch new file mode 100644 index 00000000000..7b3c00b5ee0 --- /dev/null +++ b/tools/genext2fs/patches/400-byteswap_fix.patch @@ -0,0 +1,44 @@ +Index: genext2fs/genext2fs.c +=================================================================== +--- genext2fs.orig/genext2fs.c 2011-11-29 17:36:06.000000000 +0100 ++++ genext2fs/genext2fs.c 2011-11-29 17:37:37.000000000 +0100 +@@ -1779,7 +1779,8 @@ + assert(nod->i_block[EXT2_DIND_BLOCK] != 0); + for(i = 0; i < BLOCKSIZE/4; i++) + if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) +- swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])); ++ if (((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]) ++ swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])); + swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK])); + if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4) + return; +@@ -1792,7 +1793,8 @@ + (BLOCKSIZE/4)*(BLOCKSIZE/4) + + i*(BLOCKSIZE/4)*(BLOCKSIZE/4) + + j*(BLOCKSIZE/4)) ) +- swap_block(get_blk(fs,b2[j])); ++ if (b2[j]) ++ swap_block(get_blk(fs,b2[j])); + else { + done = 1; + break; +@@ -1825,7 +1827,8 @@ + swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK])); + for(i = 0; i < BLOCKSIZE/4; i++) + if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) +- swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])); ++ if (((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]) ++ swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])); + if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4) + return; + /* Adding support for triple indirection */ +@@ -1839,7 +1842,8 @@ + (BLOCKSIZE/4)*(BLOCKSIZE/4) + + i*(BLOCKSIZE/4)*(BLOCKSIZE/4) + + j*(BLOCKSIZE/4)) ) +- swap_block(get_blk(fs,b2[j])); ++ if (b2[j]) ++ swap_block(get_blk(fs,b2[j])); + else { + done = 1; + break; diff --git a/tools/gengetopt/Makefile b/tools/gengetopt/Makefile new file mode 100644 index 00000000000..6d2b85e6582 --- /dev/null +++ b/tools/gengetopt/Makefile @@ -0,0 +1,30 @@ +# +# Copyright (C) 2014 OpenWrt.org +# +# This is free software, licengengetopt under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=gengetopt +PKG_VERSION:=2.22.6 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@GNU/$(PKG_NAME) +PKG_HASH:=30b05a88604d71ef2a42a2ef26cd26df242b41f5b011ad03083143a31d9b01f7 + +HOST_FIXUP := autoreconf + +HOST_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Install + $(INSTALL_BIN) $(HOST_BUILD_DIR)/src/gengetopt $(STAGING_DIR_HOST)/bin/ +endef + +define Host/Clean + rm -f $(STAGING_DIR_HOST)/bin/gengetopt +endef + +$(eval $(call HostBuild)) diff --git a/tools/gengetopt/patches/100-dependency_fix.patch b/tools/gengetopt/patches/100-dependency_fix.patch new file mode 100644 index 00000000000..69cb598b7d8 --- /dev/null +++ b/tools/gengetopt/patches/100-dependency_fix.patch @@ -0,0 +1,11 @@ +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -51,7 +51,7 @@ libgengetopt_la_LIBADD = $(top_builddir) + @LTLIBOBJS@ \ + skels/libgen.la + +-LDADD = $(top_builddir)/src/libgengetopt.la ++LDADD = libgengetopt.la + + EXTRA_DIST = parser.h argsdef.h gengetopt.h ggos.h gm.h gnugetopt.h \ + cmdline.c cmdline.h \ diff --git a/tools/gengetopt/patches/200-no_docs_tests.patch b/tools/gengetopt/patches/200-no_docs_tests.patch new file mode 100644 index 00000000000..d3930696ffe --- /dev/null +++ b/tools/gengetopt/patches/200-no_docs_tests.patch @@ -0,0 +1,13 @@ +diff -urN gengetopt-2.22.6/Makefile.am gengetopt-2.22.6.new/Makefile.am +--- gengetopt-2.22.6/Makefile.am 2012-11-02 06:26:54.000000000 -0700 ++++ gengetopt-2.22.6.new/Makefile.am 2015-05-21 17:43:15.183083542 -0700 +@@ -18,6 +18,6 @@ + ACLOCAL_AMFLAGS = -I m4 -I gl/m4 + + EXTRA_DIST = configure TODO LICENSE gl/m4/gnulib-cache.m4 +-SUBDIRS = gl src doc tests ++SUBDIRS = gl src + +-gengetoptdoc_DATA = ChangeLog COPYING NEWS THANKS INSTALL README LICENSE +\ No newline at end of file ++gengetoptdoc_DATA = ChangeLog COPYING NEWS THANKS INSTALL README LICENSE diff --git a/tools/gmp/Makefile b/tools/gmp/Makefile index 1bee5f2b1f9..19dc8215f3f 100644 --- a/tools/gmp/Makefile +++ b/tools/gmp/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2009 -2010 OpenWrt.org +# Copyright (C) 2009-2016 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,11 +7,15 @@ include $(TOPDIR)/rules.mk PKG_NAME:=gmp -PKG_VERSION:=5.0.1 +PKG_VERSION:=6.1.2 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNU/gmp/ -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 -PKG_MD5SUM:=6bac6df75c192a13419dfd71d19240a7 +PKG_HASH:=87b565e89a9a684fe4ebeeddb8399dce2599f9c9049854ca8c0dfbdea0e21912 + +HOST_FIXUP:=autoreconf + +HOST_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/host-build.mk @@ -20,7 +24,12 @@ unexport CFLAGS HOST_CONFIGURE_ARGS += \ --enable-static \ --disable-shared \ + --disable-assembly \ --enable-cxx \ --enable-mpbsd +ifeq ($(GNU_HOST_NAME),x86_64-linux-gnux32) +HOST_CONFIGURE_ARGS += ABI=x32 +endif + $(eval $(call HostBuild)) diff --git a/tools/gmp/patches/000-OE-amd64.patch b/tools/gmp/patches/000-OE-amd64.patch deleted file mode 100644 index 957a7224eac..00000000000 --- a/tools/gmp/patches/000-OE-amd64.patch +++ /dev/null @@ -1,16 +0,0 @@ -Index: gmp-5.0.1/longlong.h -=================================================================== ---- gmp-5.0.1.orig/longlong.h -+++ gmp-5.0.1/longlong.h -@@ -849,8 +849,10 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO ( - count is only an int. */ - #define count_trailing_zeros(count, x) \ - do { \ -+ UDItype __cbtmp; \ - ASSERT ((x) != 0); \ -- __asm__ ("bsfq %1,%q0" : "=r" (count) : "rm" ((UDItype)(x))); \ -+ __asm__ ("bsfq %1,%0" : "=r" (__cbtmp) : "rm" ((UDItype)(x))); \ -+ (count) = __cbtmp; \ - } while (0) - #endif /* x86_64 */ - diff --git a/tools/gmp/patches/000-OE-configure.patch b/tools/gmp/patches/000-OE-configure.patch deleted file mode 100644 index f89ce0770ee..00000000000 --- a/tools/gmp/patches/000-OE-configure.patch +++ /dev/null @@ -1,193 +0,0 @@ -diff -rdup gmp-5.0.1.oorig/acinclude.m4 gmp-5.0.1/acinclude.m4 ---- gmp-5.0.1.oorig/acinclude.m4 2010-02-06 13:43:13.000000000 +0100 -+++ gmp-5.0.1/acinclude.m4 2010-02-08 17:19:44.000000000 +0100 -@@ -30,23 +30,23 @@ dnl a_out.exe - OpenVMS DEC C called - dnl conftest.exe - various DOS compilers - - --define(IA64_PATTERN, -+define([IA64_PATTERN], - [[ia64*-*-* | itanium-*-* | itanium2-*-*]]) - - dnl Need to be careful not to match m6811, m6812, m68hc11 and m68hc12, all - dnl of which config.sub accepts. (Though none of which are likely to work - dnl with GMP.) - dnl --define(M68K_PATTERN, -+define([M68K_PATTERN], - [[m68k-*-* | m68[0-9][0-9][0-9]-*-*]]) - --define(POWERPC64_PATTERN, -+define([POWERPC64_PATTERN], - [[powerpc64-*-* | powerpc64le-*-* | powerpc620-*-* | powerpc630-*-* | powerpc970-*-* | power[3-9]-*-*]]) - --define(X86_PATTERN, -+define([X86_PATTERN], - [[i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | geode*-*-* | atom-*-*]]) - --define(X86_64_PATTERN, -+define([X86_64_PATTERN], - [[athlon64-*-* | pentium4-*-* | atom-*-* | core2-*-* | corei-*-* | x86_64-*-* | nano-*-*]]) - - dnl GMP_FAT_SUFFIX(DSTVAR, DIRECTORY) -@@ -64,7 +64,7 @@ dnl x86 -> x86 - dnl x86/k6 -> k6 - dnl x86/k6/mmx -> k6_mmx - --define(GMP_FAT_SUFFIX, -+define([GMP_FAT_SUFFIX], - [[$1=`echo $2 | sed -e '/\//s:^[^/]*/::' -e 's:[\\/]:_:g'`]]) - - -@@ -73,7 +73,7 @@ dnl ---------------------------------- - dnl Emit code to remove any occurrence of ITEM from $LISTVAR. ITEM can be a - dnl shell expression like $foo if desired. - --define(GMP_REMOVE_FROM_LIST, -+define([GMP_REMOVE_FROM_LIST], - [remove_from_list_tmp= - for remove_from_list_i in $[][$1]; do - if test $remove_from_list_i = [$2]; then :; -@@ -89,12 +89,12 @@ dnl GMP_STRIP_PATH(subdir) - dnl ---------------------- - dnl Strip entries */subdir from $path and $fat_path. - --define(GMP_STRIP_PATH, -+define([GMP_STRIP_PATH], - [GMP_STRIP_PATH_VAR(path, [$1]) - GMP_STRIP_PATH_VAR(fat_path, [$1]) - ]) - --define(GMP_STRIP_PATH_VAR, -+define([GMP_STRIP_PATH_VAR], - [tmp_path= - for i in $[][$1]; do - case $i in -@@ -115,7 +115,7 @@ dnl - dnl Dummy value for GMP_LIMB_BITS is enough - dnl for all current configure-time uses of gmp.h. - --define(GMP_INCLUDE_GMP_H, -+define([GMP_INCLUDE_GMP_H], - [[#define __GMP_WITHIN_CONFIGURE 1 /* ignore template stuff */ - #define GMP_NAIL_BITS $GMP_NAIL_BITS - #define GMP_LIMB_BITS 123 -@@ -130,7 +130,7 @@ dnl Expand at autoconf time to the valu - dnl FILE. The regexps here aren't very rugged, but are enough for gmp. - dnl /dev/null as a parameter prevents a hang if $2 is accidentally omitted. - --define(GMP_HEADER_GETVAL, -+define([GMP_HEADER_GETVAL], - [patsubst(patsubst( - esyscmd([grep "^#define $1 " $2 /dev/null 2>/dev/null]), - [^.*$1[ ]+],[]), -@@ -144,7 +144,7 @@ dnl The gmp version number, extracted f - dnl autoconf time. Two digits like 3.0 if patchlevel <= 0, or three digits - dnl like 3.0.1 if patchlevel > 0. - --define(GMP_VERSION, -+define([GMP_VERSION], - [GMP_HEADER_GETVAL(__GNU_MP_VERSION,gmp-h.in)[]dnl - .GMP_HEADER_GETVAL(__GNU_MP_VERSION_MINOR,gmp-h.in)[]dnl - .GMP_HEADER_GETVAL(__GNU_MP_VERSION_PATCHLEVEL,gmp-h.in)]) -@@ -1506,7 +1506,9 @@ esac - echo ["define(<CONFIG_TOP_SRCDIR>,<\`$tmp'>)"] >>$gmp_tmpconfigm4 - - # All CPUs use asm-defs.m4 --echo ["include][(CONFIG_TOP_SRCDIR\`/mpn/asm-defs.m4')"] >>$gmp_tmpconfigm4i -+echo -n ["include("] >>$gmp_tmpconfigm4i -+echo -n ["CONFIG_TOP_SRCDIR\`/mpn/asm-defs.m4'"] >>$gmp_tmpconfigm4i -+echo [")"] >>$gmp_tmpconfigm4i - ]) - - -diff -rdup gmp-5.0.1.oorig/configure.in gmp-5.0.1/configure.in ---- gmp-5.0.1.oorig/configure.in 2010-02-06 13:43:13.000000000 +0100 -+++ gmp-5.0.1/configure.in 2010-02-08 17:18:30.000000000 +0100 -@@ -29,12 +29,6 @@ AC_REVISION($Revision$) - AC_PREREQ(2.59) - AC_INIT(GNU MP, GMP_VERSION, gmp-bugs@gmplib.org, gmp) - AC_CONFIG_SRCDIR(gmp-impl.h) --m4_pattern_forbid([^[ \t]*GMP_]) --m4_pattern_allow(GMP_LDFLAGS) --m4_pattern_allow(GMP_LIMB_BITS) --m4_pattern_allow(GMP_MPARAM_H_SUGGEST) --m4_pattern_allow(GMP_NAIL_BITS) --m4_pattern_allow(GMP_NUMB_BITS) - - # If --target is not used then $target_alias is empty, but if say - # "./configure athlon-pc-freebsd3.5" is used, then all three of -@@ -303,7 +297,7 @@ AH_VERBATIM([HAVE_HOST_CPU_1], - # After GMP specific searches and tests, the standard autoconf AC_PROG_CC is - # called. User selections of CC etc are respected. - # --# Care is taken not to use macros like AC_TRY_COMPILE during the GMP -+# Care is taken not to use macros like AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[],[]) during the GMP - # pre-testing, since they of course depend on AC_PROG_CC, and also some of - # them cache their results, which is not wanted. - # -@@ -395,7 +389,7 @@ abilist="standard" - # FIXME: We'd like to prefer an ANSI compiler, perhaps by preferring - # c89 over cc here. But note that on HP-UX c89 provides a castrated - # environment, and would want to be excluded somehow. Maybe --# AC_PROG_CC_STDC already does enough to stick cc into ANSI mode and -+# already does enough to stick cc into ANSI mode and - # we don't need to worry. - # - cclist="gcc cc" -@@ -1580,7 +1574,7 @@ esac - CFLAGS_or_unset=${CFLAGS-'(unset)'} - CPPFLAGS_or_unset=${CPPFLAGS-'(unset)'} - --cat >&AC_FD_CC <<EOF -+cat >&AS_MESSAGE_LOG_FD() <<EOF - User: - ABI=$ABI - CC=$CC -@@ -1987,7 +1981,6 @@ AC_SUBST(DEFN_LONG_LONG_LIMB) - - # The C compiler and preprocessor, put into ANSI mode if possible. - AC_PROG_CC --AC_PROG_CC_STDC - AC_PROG_CPP - GMP_H_ANSI - -@@ -2010,11 +2003,11 @@ AC_SUBST(CCAS) - - # The C++ compiler, if desired. - want_cxx=no -+AC_PROG_CXX - if test $enable_cxx != no; then - test_CXXFLAGS=${CXXFLAGS+set} -- AC_PROG_CXX - -- echo "CXXFLAGS chosen by autoconf: $CXXFLAGS" >&AC_FD_CC -+ echo "CXXFLAGS chosen by autoconf: $CXXFLAGS" >&AS_MESSAGE_LOG_FD() - cxxflags_ac_prog_cxx=$CXXFLAGS - cxxflags_list=ac_prog_cxx - -@@ -2120,7 +2113,7 @@ case $host in - esac - - --cat >&AC_FD_CC <<EOF -+cat >&AS_MESSAGE_LOG_FD() <<EOF - Decided: - ABI=$ABI - CC=$CC -@@ -3376,7 +3369,7 @@ GMP_FINISH - # FIXME: Upcoming version of autoconf/automake may not like broken lines. - # Right now automake isn't accepting the new AC_CONFIG_FILES scheme. - --AC_OUTPUT(Makefile \ -+AC_CONFIG_FILES([Makefile \ - mpbsd/Makefile mpf/Makefile mpn/Makefile mpq/Makefile \ - mpz/Makefile printf/Makefile scanf/Makefile cxx/Makefile \ - tests/Makefile tests/devel/Makefile tests/mpbsd/Makefile \ -@@ -3385,4 +3378,5 @@ AC_OUTPUT(Makefile \ - tests/cxx/Makefile \ - doc/Makefile tune/Makefile \ - demos/Makefile demos/calc/Makefile demos/expr/Makefile \ -- gmp.h:gmp-h.in mp.h:mp-h.in) -+ gmp.h:gmp-h.in mp.h:mp-h.in]) -+AC_OUTPUT diff --git a/tools/include/byteswap.h b/tools/include/byteswap.h index fe279ceb2c0..015f09740ad 100644 --- a/tools/include/byteswap.h +++ b/tools/include/byteswap.h @@ -1,3 +1,5 @@ #if defined(__linux__) || defined(__CYGWIN__) #include_next <byteswap.h> +#else +#include <endian.h> #endif diff --git a/tools/sstrip/include/elf.h b/tools/include/elf.h index eae96d00037..036a176345e 100644 --- a/tools/sstrip/include/elf.h +++ b/tools/include/elf.h @@ -1,5 +1,5 @@ /* This file defines standard ELF types, structures, and macros. - Copyright (C) 1995-1999,2000,2001,2002,2003 Free Software Foundation, Inc. + Copyright (C) 1995-2012 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 @@ -13,15 +13,12 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _ELF_H #define _ELF_H 1 -__BEGIN_DECLS - /* Standard ELF types. */ #include <stdint.h> @@ -139,7 +136,8 @@ typedef struct #define ELFOSABI_SYSV 0 /* Alias. */ #define ELFOSABI_HPUX 1 /* HP-UX */ #define ELFOSABI_NETBSD 2 /* NetBSD. */ -#define ELFOSABI_LINUX 3 /* Linux. */ +#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ +#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ #define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ #define ELFOSABI_AIX 7 /* IBM AIX. */ #define ELFOSABI_IRIX 8 /* SGI Irix. */ @@ -147,6 +145,7 @@ typedef struct #define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ #define ELFOSABI_MODESTO 11 /* Novell Modesto. */ #define ELFOSABI_OPENBSD 12 /* OpenBSD. */ +#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ #define ELFOSABI_ARM 97 /* ARM */ #define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ @@ -246,7 +245,9 @@ typedef struct #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_NUM 95 +#define EM_TILEPRO 188 /* Tilera TILEPro */ +#define EM_TILEGX 191 /* Tilera TILE-Gx */ +#define EM_NUM 192 /* If it is necessary to assign new unofficial EM_* values, please pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the @@ -295,6 +296,10 @@ typedef struct #define SHN_UNDEF 0 /* Undefined section */ #define SHN_LORESERVE 0xff00 /* Start of reserved indices */ #define SHN_LOPROC 0xff00 /* Start of processor-specific */ +#define SHN_BEFORE 0xff00 /* Order section before all others + (Solaris). */ +#define SHN_AFTER 0xff01 /* Order section after all others + (Solaris). */ #define SHN_HIPROC 0xff1f /* End of processor-specific */ #define SHN_LOOS 0xff20 /* Start of OS-specific */ #define SHN_HIOS 0xff3f /* End of OS-specific */ @@ -323,7 +328,9 @@ typedef struct #define SHT_GROUP 17 /* Section group */ #define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ #define SHT_NUM 19 /* Number of defined types. */ -#define SHT_LOOS 0x60000000 /* Start OS-specific */ +#define SHT_LOOS 0x60000000 /* Start OS-specific. */ +#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ +#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ #define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ #define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ #define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ @@ -355,6 +362,10 @@ typedef struct #define SHF_TLS (1 << 10) /* Section hold thread-local data. */ #define SHF_MASKOS 0x0ff00000 /* OS-specific. */ #define SHF_MASKPROC 0xf0000000 /* Processor-specific */ +#define SHF_ORDERED (1 << 30) /* Special ordering requirement + (Solaris). */ +#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless + referenced or allocated (Solaris).*/ /* Section group handling. */ #define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ @@ -431,6 +442,7 @@ typedef struct #define STB_WEAK 2 /* Weak symbol */ #define STB_NUM 3 /* Number of defined types. */ #define STB_LOOS 10 /* Start of OS-specific */ +#define STB_GNU_UNIQUE 10 /* Unique symbol. */ #define STB_HIOS 12 /* End of OS-specific */ #define STB_LOPROC 13 /* Start of processor-specific */ #define STB_HIPROC 15 /* End of processor-specific */ @@ -446,6 +458,7 @@ typedef struct #define STT_TLS 6 /* Symbol is thread-local data object*/ #define STT_NUM 7 /* Number of defined types. */ #define STT_LOOS 10 /* Start of OS-specific */ +#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ #define STT_HIOS 12 /* End of OS-specific */ #define STT_LOPROC 13 /* Start of processor-specific */ #define STT_HIPROC 15 /* End of processor-specific */ @@ -543,6 +556,12 @@ typedef struct Elf64_Xword p_align; /* Segment alignment */ } Elf64_Phdr; +/* Special value for e_phnum. This indicates that the real number of + program headers is too large to fit into e_phnum. Instead the real + value is in the field sh_info of section 0. */ + +#define PN_XNUM 0xffff + /* Legal values for p_type (segment type). */ #define PT_NULL 0 /* Program header table entry unused */ @@ -557,6 +576,7 @@ typedef struct #define PT_LOOS 0x60000000 /* Start of OS-specific */ #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_LOSUNW 0x6ffffffa #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ #define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ @@ -590,7 +610,14 @@ typedef struct #define NT_UTSNAME 15 /* Contains copy of utsname struct */ #define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ #define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ -#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct*/ +#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ +#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_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_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 */ /* Legal values for the note segment descriptor types for object files. */ @@ -688,6 +715,9 @@ typedef struct If any adjustment is made to the ELF object after it has been built these entries will need to be adjusted. */ #define DT_ADDRRNGLO 0x6ffffe00 +#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ +#define DT_TLSDESC_PLT 0x6ffffef6 +#define DT_TLSDESC_GOT 0x6ffffef7 #define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ #define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ #define DT_CONFIG 0x6ffffefa /* Configuration information. */ @@ -698,7 +728,7 @@ typedef struct #define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ #define DT_ADDRRNGHI 0x6ffffeff #define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ -#define DT_ADDRNUM 10 +#define DT_ADDRNUM 11 /* The versioning entry types. The next are defined as part of the GNU extension. */ @@ -888,23 +918,25 @@ typedef struct typedef struct { - int a_type; /* Entry type */ + uint32_t a_type; /* Entry type */ union { - long int a_val; /* Integer value */ - void *a_ptr; /* Pointer value */ - void (*a_fcn) (void); /* Function pointer value */ + uint32_t a_val; /* Integer value */ + /* We use to have pointer elements added here. We cannot do that, + though, since it does not work when using 32-bit definitions + on 64-bit platforms and vice versa. */ } a_un; } Elf32_auxv_t; typedef struct { - long int a_type; /* Entry type */ + uint64_t a_type; /* Entry type */ union { - long int a_val; /* Integer value */ - void *a_ptr; /* Pointer value */ - void (*a_fcn) (void); /* Function pointer value */ + uint64_t a_val; /* Integer value */ + /* We use to have pointer elements added here. We cannot do that, + though, since it does not work when using 32-bit definitions + on 64-bit platforms and vice versa. */ } a_un; } Elf64_auxv_t; @@ -947,11 +979,23 @@ typedef struct #define AT_SECURE 23 /* Boolean, was exec setuid-like? */ +#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ + +#define AT_RANDOM 25 /* Address of 16 random bytes. */ + +#define AT_EXECFN 31 /* Filename of executable. */ + /* Pointer to the global system page used for system calls and other nice things. */ #define AT_SYSINFO 32 #define AT_SYSINFO_EHDR 33 +/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains + log2 of line size; mask those to get cache size. */ +#define AT_L1I_CACHESHAPE 34 +#define AT_L1D_CACHESHAPE 35 +#define AT_L2_CACHESHAPE 36 +#define AT_L3_CACHESHAPE 37 /* Note section contents. Each entry in the note section begins with a header of a fixed form. */ @@ -993,15 +1037,31 @@ typedef struct word 2: minor version of the ABI word 3: subminor version of the ABI */ -#define ELF_NOTE_ABI 1 +#define NT_GNU_ABI_TAG 1 +#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ -/* Known OSes. These value can appear in word 0 of an ELF_NOTE_ABI - note section entry. */ +/* Known OSes. These values can appear in word 0 of an + NT_GNU_ABI_TAG note section entry. */ #define ELF_NOTE_OS_LINUX 0 #define ELF_NOTE_OS_GNU 1 #define ELF_NOTE_OS_SOLARIS2 2 #define ELF_NOTE_OS_FREEBSD 3 +/* Synthetic hwcap information. The descriptor begins with two words: + word 0: number of entries + word 1: bitmask of enabled entries + Then follow variable-length entries, one byte followed by a + '\0'-terminated hwcap name string. The byte gives the bit + number to test if enabled, (1U << bit) & bitmask. */ +#define NT_GNU_HWCAP 2 + +/* Build ID bits as generated by ld --build-id. + The descriptor consists of any nonzero number of bytes. */ +#define NT_GNU_BUILD_ID 3 + +/* Version note generated by GNU gold containing a version string. */ +#define NT_GNU_GOLD_VERSION 4 + /* Move records. */ typedef struct @@ -1062,8 +1122,29 @@ typedef struct #define R_68K_GLOB_DAT 20 /* Create GOT entry */ #define R_68K_JMP_SLOT 21 /* Create PLT entry */ #define R_68K_RELATIVE 22 /* Adjust by program base */ +#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ +#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ +#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ +#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ +#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ +#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ +#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ +#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ +#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ +#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ +#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ +#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ +#define R_68K_TLS_LE32 37 /* 32 bit offset relative to + static TLS block */ +#define R_68K_TLS_LE16 38 /* 16 bit offset relative to + static TLS block */ +#define R_68K_TLS_LE8 39 /* 8 bit offset relative to + static TLS block */ +#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ +#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ +#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ /* Keep this the last entry. */ -#define R_68K_NUM 23 +#define R_68K_NUM 43 /* Intel 80386 specific definitions. */ @@ -1117,14 +1198,24 @@ typedef struct #define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ #define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ #define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ +/* 38? */ +#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ +#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS + descriptor for + relaxation. */ +#define R_386_TLS_DESC 41 /* TLS descriptor containing + pointer to code and to + argument, returning the TLS + offset for the symbol. */ +#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ /* Keep this the last entry. */ -#define R_386_NUM 38 +#define R_386_NUM 43 /* SUN SPARC specific definitions. */ /* Legal values for ST_TYPE subfield of st_info (symbol type). */ -#define STT_REGISTER 13 /* Global register reserved to app. */ +#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ /* Values for Elf64_Ehdr.e_flags. */ @@ -1186,6 +1277,7 @@ typedef struct #define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ #define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ #define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ +#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ #define R_SPARC_7 43 /* Direct 7 bit */ #define R_SPARC_5 44 /* Direct 5 bit */ #define R_SPARC_6 45 /* Direct 6 bit */ @@ -1223,23 +1315,28 @@ typedef struct #define R_SPARC_TLS_DTPOFF64 77 #define R_SPARC_TLS_TPOFF32 78 #define R_SPARC_TLS_TPOFF64 79 +#define R_SPARC_GOTDATA_HIX22 80 +#define R_SPARC_GOTDATA_LOX10 81 +#define R_SPARC_GOTDATA_OP_HIX22 82 +#define R_SPARC_GOTDATA_OP_LOX10 83 +#define R_SPARC_GOTDATA_OP 84 +#define R_SPARC_H34 85 +#define R_SPARC_SIZE32 86 +#define R_SPARC_SIZE64 87 +#define R_SPARC_WDISP10 88 +#define R_SPARC_JMP_IREL 248 +#define R_SPARC_IRELATIVE 249 +#define R_SPARC_GNU_VTINHERIT 250 +#define R_SPARC_GNU_VTENTRY 251 +#define R_SPARC_REV32 252 /* Keep this the last entry. */ -#define R_SPARC_NUM 80 +#define R_SPARC_NUM 253 /* For Sparc64, legal values for d_tag of Elf64_Dyn. */ #define DT_SPARC_REGISTER 0x70000001 #define DT_SPARC_NUM 2 -/* Bits present in AT_HWCAP, primarily for Sparc32. */ - -#define HWCAP_SPARC_FLUSH 1 /* The cpu supports flush insn. */ -#define HWCAP_SPARC_STBAR 2 -#define HWCAP_SPARC_SWAP 4 -#define HWCAP_SPARC_MULDIV 8 -#define HWCAP_SPARC_V9 16 /* The cpu is v9, so v8plus is ok. */ -#define HWCAP_SPARC_ULTRA3 32 - /* MIPS R3000 specific definitions. */ /* Legal values for e_flags field of Elf32_Ehdr. */ @@ -1342,6 +1439,7 @@ typedef struct #define STO_MIPS_INTERNAL 0x1 #define STO_MIPS_HIDDEN 0x2 #define STO_MIPS_PROTECTED 0x3 +#define STO_MIPS_PLT 0x8 #define STO_MIPS_SC_ALIGN_UNUSED 0xff /* MIPS specific values for `st_info'. */ @@ -1474,8 +1572,24 @@ typedef struct #define R_MIPS_PJUMP 35 #define R_MIPS_RELGOT 36 #define R_MIPS_JALR 37 +#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ +#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ +#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ +#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ +#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ +#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ +#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ +#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ +#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ +#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ +#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ +#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_COPY 126 +#define R_MIPS_JUMP_SLOT 127 /* Keep this the last entry. */ -#define R_MIPS_NUM 38 +#define R_MIPS_NUM 128 /* Legal values for p_type field of Elf32_Phdr. */ @@ -1541,7 +1655,13 @@ typedef struct #define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ #define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ #define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ -#define DT_MIPS_NUM 0x32 +/* The address of .got.plt in an executable using the new non-PIC ABI. */ +#define DT_MIPS_PLTGOT 0x70000032 +/* The base of the PLT in an executable using the new non-PIC ABI if that + 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 /* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ @@ -1671,6 +1791,8 @@ typedef Elf32_Addr Elf32_Conflict; #define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ #define R_PARISC_FPTR64 64 /* 64 bits function address. */ #define R_PARISC_PLABEL32 65 /* 32 bits function address. */ +#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ +#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ #define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ #define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ #define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ @@ -1731,6 +1853,26 @@ typedef Elf32_Addr Elf32_Conflict; #define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ #define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ #define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_GNU_VTENTRY 232 +#define R_PARISC_GNU_VTINHERIT 233 +#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ +#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ +#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ +#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ +#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ +#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ +#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ +#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ +#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ +#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ +#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ +#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ +#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L +#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R +#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L +#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R +#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 +#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 #define R_PARISC_HIRESERVE 255 /* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ @@ -1834,6 +1976,9 @@ typedef Elf32_Addr Elf32_Conflict; #define LITUSE_ALPHA_TLS_GD 4 #define LITUSE_ALPHA_TLS_LDM 5 +/* Legal values for d_tag of Elf64_Dyn. */ +#define DT_ALPHA_PLTRO (DT_LOPROC + 0) +#define DT_ALPHA_NUM 1 /* PowerPC specific declarations */ @@ -1914,9 +2059,6 @@ typedef Elf32_Addr Elf32_Conflict; #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 */ -/* Keep this the last entry. */ -#define R_PPC_NUM 95 - /* The remaining relocs are from the Embedded ELF ABI, and are not in the SVR4 ELF ABI. */ #define R_PPC_EMB_NADDR32 101 @@ -1944,10 +2086,22 @@ typedef Elf32_Addr Elf32_Conflict; #define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ #define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ +/* GNU extension to support local ifunc. */ +#define R_PPC_IRELATIVE 248 + +/* GNU relocs used in PIC code sequences. */ +#define R_PPC_REL16 249 /* half16 (sym+add-.) */ +#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ +#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ +#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ + /* This is a phony reloc to handle any old fashioned TOC16 references that may still be in object files. */ #define R_PPC_TOC16 255 +/* PowerPC specific values for the Dyn d_tag field. */ +#define DT_PPC_GOT (DT_LOPROC + 0) +#define DT_PPC_NUM 1 /* PowerPC64 relocations defined by the ABIs */ #define R_PPC64_NONE R_PPC_NONE @@ -2061,52 +2215,83 @@ typedef Elf32_Addr Elf32_Conflict; #define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ #define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ -/* Keep this the last entry. */ -#define R_PPC64_NUM 107 +/* GNU extension to support local ifunc. */ +#define R_PPC64_JMP_IREL 247 +#define R_PPC64_IRELATIVE 248 +#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ +#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ +#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ +#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ /* PowerPC64 specific values for the Dyn d_tag field. */ #define DT_PPC64_GLINK (DT_LOPROC + 0) -#define DT_PPC64_NUM 1 +#define DT_PPC64_OPD (DT_LOPROC + 1) +#define DT_PPC64_OPDSZ (DT_LOPROC + 2) +#define DT_PPC64_NUM 3 /* ARM specific declarations */ /* Processor specific flags for the ELF header e_flags field. */ -#define EF_ARM_RELEXEC 0x01 -#define EF_ARM_HASENTRY 0x02 -#define EF_ARM_INTERWORK 0x04 -#define EF_ARM_APCS_26 0x08 -#define EF_ARM_APCS_FLOAT 0x10 -#define EF_ARM_PIC 0x20 -#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ -#define EF_ARM_NEW_ABI 0x80 -#define EF_ARM_OLD_ABI 0x100 +#define EF_ARM_RELEXEC 0x01 +#define EF_ARM_HASENTRY 0x02 +#define EF_ARM_INTERWORK 0x04 +#define EF_ARM_APCS_26 0x08 +#define EF_ARM_APCS_FLOAT 0x10 +#define EF_ARM_PIC 0x20 +#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ +#define EF_ARM_NEW_ABI 0x80 +#define EF_ARM_OLD_ABI 0x100 +#define EF_ARM_SOFT_FLOAT 0x200 +#define EF_ARM_VFP_FLOAT 0x400 +#define EF_ARM_MAVERICK_FLOAT 0x800 + /* Other constants defined in the ARM ELF spec. version B-01. */ /* NB. These conflict with values defined above. */ #define EF_ARM_SYMSARESORTED 0x04 -#define EF_ARM_DYNSYMSUSESEGIDX 0x08 +#define EF_ARM_DYNSYMSUSESEGIDX 0x08 #define EF_ARM_MAPSYMSFIRST 0x10 #define EF_ARM_EABIMASK 0XFF000000 -#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) -#define EF_ARM_EABI_UNKNOWN 0x00000000 -#define EF_ARM_EABI_VER1 0x01000000 -#define EF_ARM_EABI_VER2 0x02000000 +/* Constants defined in AAELF. */ +#define EF_ARM_BE8 0x00800000 +#define EF_ARM_LE8 0x00400000 + +#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) +#define EF_ARM_EABI_UNKNOWN 0x00000000 +#define EF_ARM_EABI_VER1 0x01000000 +#define EF_ARM_EABI_VER2 0x02000000 +#define EF_ARM_EABI_VER3 0x03000000 +#define EF_ARM_EABI_VER4 0x04000000 +#define EF_ARM_EABI_VER5 0x05000000 -/* Additional symbol types for Thumb */ -#define STT_ARM_TFUNC 0xd +/* Additional symbol types for Thumb. */ +#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ +#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ /* ARM-specific values for sh_flags */ -#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ -#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined - in the input to a link step */ +#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ +#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined + in the input to a link step. */ /* ARM-specific program header flags */ -#define PF_ARM_SB 0x10000000 /* Segment contains the location - addressed by the static base */ +#define PF_ARM_SB 0x10000000 /* Segment contains the location + addressed by the static base. */ +#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ +#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ + +/* Processor specific values for the Phdr p_type field. */ +#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ +#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ +#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ + /* ARM relocs. */ + #define R_ARM_NONE 0 /* No reloc */ #define R_ARM_PC24 1 /* PC relative 26 bit branch */ #define R_ARM_ABS32 2 /* Direct 32 bit */ @@ -2120,10 +2305,14 @@ typedef Elf32_Addr Elf32_Conflict; #define R_ARM_THM_PC22 10 #define R_ARM_THM_PC8 11 #define R_ARM_AMP_VCALL9 12 -#define R_ARM_SWI24 13 +#define R_ARM_SWI24 13 /* Obsolete static relocation. */ +#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */ #define R_ARM_THM_SWI8 14 #define R_ARM_XPC25 15 #define R_ARM_THM_XPC22 16 +#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ +#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ +#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ #define R_ARM_COPY 20 /* Copy symbol at runtime */ #define R_ARM_GLOB_DAT 21 /* Create GOT entry */ #define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ @@ -2138,10 +2327,26 @@ typedef Elf32_Addr Elf32_Conflict; #define R_ARM_LDR_SBREL_11_0 35 #define R_ARM_ALU_SBREL_19_12 36 #define R_ARM_ALU_SBREL_27_20 37 +#define R_ARM_TLS_GOTDESC 90 +#define R_ARM_TLS_CALL 91 +#define R_ARM_TLS_DESCSEQ 92 +#define R_ARM_THM_TLS_CALL 93 #define R_ARM_GNU_VTENTRY 100 #define R_ARM_GNU_VTINHERIT 101 #define R_ARM_THM_PC11 102 /* thumb unconditional branch */ #define R_ARM_THM_PC9 103 /* thumb conditional branch */ +#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic + thread local data */ +#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic + thread local data */ +#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS + block */ +#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of + static TLS block offset */ +#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static + TLS block */ +#define R_ARM_THM_TLS_DESCSEQ 129 +#define R_ARM_IRELATIVE 160 #define R_ARM_RXPC25 249 #define R_ARM_RSBREL32 250 #define R_ARM_THM_RPC22 251 @@ -2162,6 +2367,9 @@ typedef Elf32_Addr Elf32_Conflict; /* Processor specific values for the Phdr p_type field. */ #define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ #define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ +#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) +#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) +#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) /* Processor specific flags for the Phdr p_flags field. */ #define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ @@ -2263,6 +2471,30 @@ typedef Elf32_Addr Elf32_Conflict; /* SH specific declarations */ +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_SH_MACH_MASK 0x1f +#define EF_SH_UNKNOWN 0x0 +#define EF_SH1 0x1 +#define EF_SH2 0x2 +#define EF_SH3 0x3 +#define EF_SH_DSP 0x4 +#define EF_SH3_DSP 0x5 +#define EF_SH4AL_DSP 0x6 +#define EF_SH3E 0x8 +#define EF_SH4 0x9 +#define EF_SH2E 0xb +#define EF_SH4A 0xc +#define EF_SH2A 0xd +#define EF_SH4_NOFPU 0x10 +#define EF_SH4A_NOFPU 0x11 +#define EF_SH4_NOMMU_NOFPU 0x12 +#define EF_SH2A_NOFPU 0x13 +#define EF_SH3_NOMMU 0x14 +#define EF_SH2A_SH4_NOFPU 0x15 +#define EF_SH2A_SH3_NOFPU 0x16 +#define EF_SH2A_SH4 0x17 +#define EF_SH2A_SH3E 0x18 + /* SH relocs. */ #define R_SH_NONE 0 #define R_SH_DIR32 1 @@ -2304,6 +2536,12 @@ typedef Elf32_Addr Elf32_Conflict; /* Keep this the last entry. */ #define R_SH_NUM 256 +/* S/390 specific definitions. */ + +/* Valid values for the e_flags field. */ + +#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ + /* Additional s390 relocs */ #define R_390_NONE 0 /* No reloc. */ @@ -2380,9 +2618,15 @@ typedef Elf32_Addr Elf32_Conflict; #define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ #define R_390_TLS_TPOFF 56 /* Negated offset in static TLS block. */ - +#define R_390_20 57 /* Direct 20 bit. */ +#define R_390_GOT20 58 /* 20 bit GOT offset. */ +#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ +#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS + block offset. */ +#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */ /* Keep this the last entry. */ -#define R_390_NUM 57 +#define R_390_NUM 62 + /* CRIS relocations. */ #define R_CRIS_NONE 0 @@ -2408,6 +2652,7 @@ typedef Elf32_Addr Elf32_Conflict; #define R_CRIS_NUM 20 + /* AMD x86-64 relocations. */ #define R_X86_64_NONE 0 /* No reloc */ #define R_X86_64_64 1 /* Direct 64 bit */ @@ -2437,9 +2682,326 @@ typedef Elf32_Addr Elf32_Conflict; #define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset to GOT entry for IE symbol */ #define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ - -#define R_X86_64_NUM 24 - -__END_DECLS +#define R_X86_64_PC64 24 /* PC relative 64 bit */ +#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ +#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative + offset to GOT */ +#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ +#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset + to GOT entry */ +#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ +#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ +#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset + to PLT entry */ +#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ +#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ +#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ +#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS + descriptor. */ +#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 */ + +#define R_X86_64_NUM 39 + + +/* AM33 relocations. */ +#define R_MN10300_NONE 0 /* No reloc. */ +#define R_MN10300_32 1 /* Direct 32 bit. */ +#define R_MN10300_16 2 /* Direct 16 bit. */ +#define R_MN10300_8 3 /* Direct 8 bit. */ +#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ +#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ +#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ +#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ +#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ +#define R_MN10300_24 9 /* Direct 24 bit. */ +#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ +#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ +#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ +#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ +#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ +#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ +#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ +#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ +#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ +#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ +#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ +#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ +#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ +#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ + +#define R_MN10300_NUM 24 + + +/* M32R relocs. */ +#define R_M32R_NONE 0 /* No reloc. */ +#define R_M32R_16 1 /* Direct 16 bit. */ +#define R_M32R_32 2 /* Direct 32 bit. */ +#define R_M32R_24 3 /* Direct 24 bit. */ +#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ +#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ +#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ +#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ +#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ +#define R_M32R_LO16 9 /* Low 16 bit. */ +#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ +#define R_M32R_GNU_VTINHERIT 11 +#define R_M32R_GNU_VTENTRY 12 +/* M32R relocs use SHT_RELA. */ +#define R_M32R_16_RELA 33 /* Direct 16 bit. */ +#define R_M32R_32_RELA 34 /* Direct 32 bit. */ +#define R_M32R_24_RELA 35 /* Direct 24 bit. */ +#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ +#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ +#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ +#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ +#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ +#define R_M32R_LO16_RELA 41 /* Low 16 bit */ +#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ +#define R_M32R_RELA_GNU_VTINHERIT 43 +#define R_M32R_RELA_GNU_VTENTRY 44 +#define R_M32R_REL32 45 /* PC relative 32 bit. */ + +#define R_M32R_GOT24 48 /* 24 bit GOT entry */ +#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ +#define R_M32R_COPY 50 /* Copy symbol at runtime */ +#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ +#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ +#define R_M32R_RELATIVE 53 /* Adjust by program base */ +#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ +#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ +#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned + low */ +#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed + low */ +#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ +#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to + GOT with unsigned low */ +#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to + GOT with signed low */ +#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to + GOT */ +#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT + with unsigned low */ +#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT + with signed low */ +#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ +#define R_M32R_NUM 256 /* Keep this the last entry. */ + + +/* TILEPro relocations. */ +#define R_TILEPRO_NONE 0 /* No reloc */ +#define R_TILEPRO_32 1 /* Direct 32 bit */ +#define R_TILEPRO_16 2 /* Direct 16 bit */ +#define R_TILEPRO_8 3 /* Direct 8 bit */ +#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */ +#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */ +#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */ +#define R_TILEPRO_LO16 7 /* Low 16 bit */ +#define R_TILEPRO_HI16 8 /* High 16 bit */ +#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */ +#define R_TILEPRO_COPY 10 /* Copy relocation */ +#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */ +#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */ +#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */ +#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */ +#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */ +#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */ +#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */ +#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */ +#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */ +#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */ +#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */ +#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */ +#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */ +#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */ +#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */ +#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */ +#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */ +#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */ +#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */ +#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */ +#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */ +#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */ +#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */ +#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */ +#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */ +#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */ +#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */ +#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */ +#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */ +#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */ +#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */ +#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */ +#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */ +#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */ +#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */ +#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */ +#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */ +#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */ +#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */ +/* Relocs 56-59 are currently not defined. */ +#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */ +#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */ +#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */ +#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */ +#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */ +#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */ +#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */ +#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */ +#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */ +#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */ +#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */ +#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */ +#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */ +#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */ + +#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ +#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ + +#define R_TILEPRO_NUM 130 + + +/* TILE-Gx relocations. */ +#define R_TILEGX_NONE 0 /* No reloc */ +#define R_TILEGX_64 1 /* Direct 64 bit */ +#define R_TILEGX_32 2 /* Direct 32 bit */ +#define R_TILEGX_16 3 /* Direct 16 bit */ +#define R_TILEGX_8 4 /* Direct 8 bit */ +#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */ +#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */ +#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */ +#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */ +#define R_TILEGX_HW0 9 /* hword 0 16-bit */ +#define R_TILEGX_HW1 10 /* hword 1 16-bit */ +#define R_TILEGX_HW2 11 /* hword 2 16-bit */ +#define R_TILEGX_HW3 12 /* hword 3 16-bit */ +#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */ +#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */ +#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */ +#define R_TILEGX_COPY 16 /* Copy relocation */ +#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */ +#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */ +#define R_TILEGX_RELATIVE 19 /* Adjust by program base */ +#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */ +#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */ +#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */ +#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */ +#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */ +#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */ +#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */ +#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */ +#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */ +#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */ +#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */ +#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */ +#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */ +#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */ +#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */ +#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */ +#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */ +#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */ +#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */ +#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */ +#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */ +#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */ +#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */ +#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */ +#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */ +#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */ +#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */ +#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */ +#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */ +#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */ +#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */ +#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */ +#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */ +#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */ +#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */ +#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */ +/* Relocs 66-71 are currently not defined. */ +#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */ +#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */ +#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */ +#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */ +/* Relocs 76-77 are currently not defined. */ +#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */ +#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */ +#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */ +#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */ +#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */ +#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */ +#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */ +#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */ +#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */ +#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */ +#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */ +#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */ +/* Relocs 90-91 are currently not defined. */ +#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */ +#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */ +/* Relocs 94-99 are currently not defined. */ +#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */ +#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */ +#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */ +#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */ +/* Relocs 104-105 are currently not defined. */ +#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */ +#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */ +#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */ +#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */ +#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */ +#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */ +#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */ +#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */ +#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */ +#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */ +#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */ +#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */ +#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */ +#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */ +#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */ +#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */ + +#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ +#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ + +#define R_TILEGX_NUM 130 #endif /* elf.h */ diff --git a/tools/include/endian.h b/tools/include/endian.h index 0f17b41da73..bba70abd833 100644 --- a/tools/include/endian.h +++ b/tools/include/endian.h @@ -15,6 +15,11 @@ #define bswap_16(x) bswap16(x) #define bswap_32(x) bswap32(x) #define bswap_64(x) bswap64(x) +#elif defined(__OpenBSD__) +#include <sys/types.h> +#define bswap_16(x) __swap16(x) +#define bswap_32(x) __swap32(x) +#define bswap_64(x) __swap64(x) #else #include <machine/endian.h> #define bswap_16(x) swap16(x) diff --git a/tools/include/getline.h b/tools/include/getline.h deleted file mode 100644 index 02df6c2f790..00000000000 --- a/tools/include/getline.h +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright (c) 2006 SPARTA, Inc. - * All rights reserved. - * - * This software was developed by SPARTA ISSO under SPAWAR contract - * N66001-04-C-6019 ("SEFOS"). - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/types.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if !defined(__linux__) && !(defined(__APPLE__) && __DARWIN_C_LEVEL >= 200809L) -/* - * Emulate glibc getline() via BSD fgetln(). - * Note that outsize is not changed unless memory is allocated. - */ -static inline ssize_t -getline(char **outbuf, size_t *outsize, FILE *fp) -{ - size_t len; - -#ifndef __CYGWIN__ - char *buf; - buf = fgetln(fp, &len); -#else - char buf[512]; - fgets(buf, sizeof(buf), fp); - len = strlen(buf); -#endif - if (buf == NULL) - return (-1); - - /* Assumes realloc() accepts NULL for ptr (C99) */ - if (*outbuf == NULL || *outsize < len + 1) { - void *tmp = realloc(*outbuf, len + 1); - if (tmp == NULL) - return (-1); - *outbuf = tmp; - *outsize = len + 1; - } - memcpy(*outbuf, buf, len); - (*outbuf)[len] = '\0'; - return (len); -} -#endif diff --git a/tools/ipkg-utils/Makefile b/tools/ipkg-utils/Makefile deleted file mode 100644 index 778260921e1..00000000000 --- a/tools/ipkg-utils/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (C) 2006 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -include $(TOPDIR)/rules.mk - -PKG_NAME:=ipkg-utils -PKG_VERSION:=1.7 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=http://handhelds.org/packages/ipkg-utils/ -PKG_MD5SUM:=da3e3ef772973d7370a6ac95f0fef9b8 - -include $(INCLUDE_DIR)/host-build.mk - -define Host/Install - $(INSTALL_BIN) \ - $(HOST_BUILD_DIR)/ipkg-build \ - $(HOST_BUILD_DIR)/ipkg-buildpackage \ - $(HOST_BUILD_DIR)/ipkg-make-index \ - $(HOST_BUILD_DIR)/ipkg.py \ - $(STAGING_DIR_HOST)/bin/ -endef - -define Host/Clean - rm -f $(STAGING_DIR)/etc/ipkg.conf - rm -f $(STAGING_DIR_HOST)/bin/ipkg* -endef - -$(eval $(call HostBuild)) diff --git a/tools/ipkg-utils/patches/100-build_clean.patch b/tools/ipkg-utils/patches/100-build_clean.patch deleted file mode 100644 index 7df272f74de..00000000000 --- a/tools/ipkg-utils/patches/100-build_clean.patch +++ /dev/null @@ -1,35 +0,0 @@ ---- a/ipkg-build -+++ b/ipkg-build -@@ -47,6 +47,19 @@ pkg_appears_sane() { - - PKG_ERROR=0 - -+ cvs_dirs=`find . -name 'CVS'` -+ if [ -n "$cvs_dirs" ]; then -+ if [ "$noclean" = "1" ]; then -+ echo "*** Warning: The following CVS directories where found. -+You probably want to remove them: " >&2 -+ ls -ld $cvs_dirs -+ echo >&2 -+ else -+ echo "*** Removing the following files: $cvs_dirs" -+ rm -rf "$cvs_dirs" -+ fi -+ fi -+ - tilde_files=`find . -name '*~'` - if [ -n "$tilde_files" ]; then - if [ "$noclean" = "1" ]; then -@@ -134,8 +147,12 @@ You probably want to chown these to a sy - - for script in $CONTROL/preinst $CONTROL/postinst $CONTROL/prerm $CONTROL/postrm; do - if [ -f $script -a ! -x $script ]; then -+ if [ "$noclean" = "1" ]; then - echo "*** Error: package script $script is not executable" >&2 - PKG_ERROR=1 -+ else -+ chmod a+x $script -+ fi - fi - done - diff --git a/tools/ipkg-utils/patches/110-buildpackage.patch b/tools/ipkg-utils/patches/110-buildpackage.patch deleted file mode 100644 index 8e62ee70cf7..00000000000 --- a/tools/ipkg-utils/patches/110-buildpackage.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/ipkg-buildpackage -+++ b/ipkg-buildpackage -@@ -30,8 +30,9 @@ - - set -e - --#SCRIPTDIR=/usr/local/bin --SCRIPTDIR=/other/kurth/ipaq-dev/familiar/dist/ipkg/util/ -+SCRIPTDIR=/usr/local/bin -+ -+IPKG_BUILD_OPTIONS=$* - - SCRIPTNAME=`basename $0` - -@@ -212,7 +213,7 @@ done - # build the ipk package - owd=`pwd` - cd .. --ipkg-build /tmp/${pkg} || exit 1 -+ipkg-build $IPKG_BUILD_OPTIONS /tmp/${pkg} || exit 1 - - rm -rf /tmp/${pkg} - diff --git a/tools/ipkg-utils/patches/111-buildpackage_conffiles.patch b/tools/ipkg-utils/patches/111-buildpackage_conffiles.patch deleted file mode 100644 index dacdaaefbdb..00000000000 --- a/tools/ipkg-utils/patches/111-buildpackage_conffiles.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/ipkg-buildpackage -+++ b/ipkg-buildpackage -@@ -190,7 +190,7 @@ fi - mkdir /tmp/${pkg}/CONTROL - - files_required="control" --files_optional="preinst postinst prerm postrm" -+files_optional="preinst postinst prerm postrm conffiles" - - for i in ${files_required} ; do - file=${CONTROL}/$i diff --git a/tools/ipkg-utils/patches/120-build_tar.patch b/tools/ipkg-utils/patches/120-build_tar.patch deleted file mode 100644 index acf6b798539..00000000000 --- a/tools/ipkg-utils/patches/120-build_tar.patch +++ /dev/null @@ -1,36 +0,0 @@ -This patch from aorlinsk fixes an issue with order in options passed to tar - - http://openwrt.org/forum/viewtopic.php?pid=8332#p8332 - - ---- a/ipkg-build -+++ b/ipkg-build -@@ -184,7 +184,7 @@ while getopts "cg:ho:v" opt; do - g ) group=$OPTARG - ogargs="$ogargs --group=$group" - ;; -- c ) outer=tar -+ c ) outer=$TAR - ;; - C ) noclean=1 - ;; -@@ -243,8 +243,8 @@ tmp_dir=$dest_dir/IPKG_BUILD.$$ - mkdir $tmp_dir - - echo $CONTROL > $tmp_dir/tarX --( cd $pkg_dir && tar $ogargs -czf $tmp_dir/data.tar.gz . -X $tmp_dir/tarX ) --( cd $pkg_dir/$CONTROL && tar $ogargs -czf $tmp_dir/control.tar.gz . ) -+( cd $pkg_dir && $TAR $ogargs -X $tmp_dir/tarX -czf $tmp_dir/data.tar.gz . ) -+( cd $pkg_dir/$CONTROL && $TAR $ogargs -czf $tmp_dir/control.tar.gz . ) - rm $tmp_dir/tarX - - echo "2.0" > $tmp_dir/debian-binary -@@ -254,7 +254,7 @@ rm -f $pkg_file - if [ "$outer" = "ar" ] ; then - ( cd $tmp_dir && ar -crf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz ) - else -- ( cd $tmp_dir && tar -zcf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz ) -+ ( cd $tmp_dir && $TAR -zcf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz ) - fi - - rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz diff --git a/tools/ipkg-utils/patches/130-tar_wildcards.patch b/tools/ipkg-utils/patches/130-tar_wildcards.patch deleted file mode 100644 index ba949c10031..00000000000 --- a/tools/ipkg-utils/patches/130-tar_wildcards.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/ipkg.py -+++ b/ipkg.py -@@ -93,9 +93,9 @@ class Package: - self.filename = os.path.basename(fn) - ## sys.stderr.write(" extracting control.tar.gz from %s\n"% (fn,)) - if self.isdeb: -- control = os.popen("ar p "+fn+" control.tar.gz | tar xfzO - '*control'","r") -+ control = os.popen("ar p "+fn+" control.tar.gz | tar xzO --wildcards -f - '*control'","r") - else: -- control = os.popen("tar xfzO "+fn+" '*control.tar.gz' | tar xfzO - '*control'","r") -+ control = os.popen("tar xzO --wildcards -f "+fn+" '*control.tar.gz' | tar xzO --wildcards -f - '*control'","r") - line = control.readline() - while 1: - if not line: break -@@ -122,7 +122,7 @@ class Package: - if self.isdeb: - data = os.popen("ar p "+fn+" data.tar.gz | tar tfz -","r") - else: -- data = os.popen("tar xfzO "+fn+" '*data.tar.gz' | tar tfz -","r") -+ data = os.popen("tar xzO --wildcards -f "+fn+" '*data.tar.gz' | tar tfz -","r") - while 1: - line = data.readline() - if not line: break diff --git a/tools/ipkg-utils/patches/140-portability.patch b/tools/ipkg-utils/patches/140-portability.patch deleted file mode 100644 index 417c4094d4d..00000000000 --- a/tools/ipkg-utils/patches/140-portability.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/ipkg-build -+++ b/ipkg-build -@@ -11,6 +11,8 @@ set -e - - version=1.0 - -+TAR="${TAR:-$(which tar)}" -+ - ipkg_extract_value() { - sed -e "s/^[^:]*:[[:space:]]*//" - } ---- a/ipkg-make-index -+++ b/ipkg-make-index -@@ -1,4 +1,4 @@ --#!/usr/bin/python -+#!/usr/bin/env python - # $Id: ipkg-make-index,v 1.20 2003/10/30 02:32:09 jamey Exp $ - - import sys, os, posixpath diff --git a/tools/ipkg-utils/patches/150-uppercase_letters.patch b/tools/ipkg-utils/patches/150-uppercase_letters.patch deleted file mode 100644 index cef200dcc86..00000000000 --- a/tools/ipkg-utils/patches/150-uppercase_letters.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/ipkg-build -+++ b/ipkg-build -@@ -133,7 +133,7 @@ You probably want to chown these to a sy - disallowed_filename=`disallowed_field Filename` - [ "$?" -ne 0 ] && PKG_ERROR=1 - -- if echo $pkg | grep '[^a-z0-9.+-]'; then -+ if echo $pkg | grep '[^a-zA-Z0-9_.+-]'; then - echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2 - PKG_ERROR=1; - fi ---- a/ipkg-buildpackage -+++ b/ipkg-buildpackage -@@ -69,7 +69,7 @@ pkg_appears_sane_control() { - required_field Maintainer >/dev/null - required_field Description >/dev/null - -- if echo $pkg | grep '[^a-z0-9.+-]'; then -+ if echo $pkg | grep '[^a-zA-Z0-9.+-]'; then - echo "ipkg-build: Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" - PKG_ERROR=1; - fi diff --git a/tools/ipkg-utils/patches/160-find.patch b/tools/ipkg-utils/patches/160-find.patch deleted file mode 100644 index 45ef3c65170..00000000000 --- a/tools/ipkg-utils/patches/160-find.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/ipkg-build -+++ b/ipkg-build -@@ -10,7 +10,8 @@ - set -e - - version=1.0 -- -+FIND="$(which find)" -+FIND="${FIND:-$(which gfind)}" - TAR="${TAR:-$(which tar)}" - - ipkg_extract_value() { -@@ -49,7 +50,7 @@ pkg_appears_sane() { - - PKG_ERROR=0 - -- cvs_dirs=`find . -name 'CVS'` -+ cvs_dirs=`$FIND . -name 'CVS'` - if [ -n "$cvs_dirs" ]; then - if [ "$noclean" = "1" ]; then - echo "*** Warning: The following CVS directories where found. -@@ -62,7 +63,7 @@ You probably want to remove them: " >&2 - fi - fi - -- tilde_files=`find . -name '*~'` -+ tilde_files=`$FIND . -name '*~'` - if [ -n "$tilde_files" ]; then - if [ "$noclean" = "1" ]; then - echo "*** Warning: The following files have names ending in '~'. -@@ -75,7 +76,7 @@ You probably want to remove them: " >&2 - fi - fi - -- large_uid_files=`find . -uid +99 || true` -+ large_uid_files=`$FIND . -uid +99 || true` - - if [ "$ogargs" = "" ] && [ -n "$large_uid_files" ]; then - echo "*** Warning: The following files have a UID greater than 99. diff --git a/tools/ipkg-utils/patches/170-resolve_conffiles.patch b/tools/ipkg-utils/patches/170-resolve_conffiles.patch deleted file mode 100644 index 31faf30a039..00000000000 --- a/tools/ipkg-utils/patches/170-resolve_conffiles.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/ipkg-build -+++ b/ipkg-build -@@ -160,12 +160,15 @@ You probably want to chown these to a sy - done - - if [ -f $CONTROL/conffiles ]; then -- for cf in `cat $CONTROL/conffiles`; do -- if [ ! -f ./$cf ]; then -- echo "*** Error: $CONTROL/conffiles mentions conffile $cf which does not exist" >&2 -- PKG_ERROR=1 -- fi -+ rm -f $CONTROL/conffiles.resolved -+ -+ for cf in `$FIND $(sed -e "s!^/!$pkg_dir/!" $CONTROL/conffiles) -type f`; do -+ echo "${cf#$pkg_dir}" >> $CONTROL/conffiles.resolved - done -+ -+ rm $CONTROL/conffiles -+ mv $CONTROL/conffiles.resolved $CONTROL/conffiles -+ chmod 0644 $CONTROL/conffiles - fi - - cd $owd diff --git a/tools/ipkg-utils/patches/180-add_installed_size.patch b/tools/ipkg-utils/patches/180-add_installed_size.patch deleted file mode 100644 index fb91a319097..00000000000 --- a/tools/ipkg-utils/patches/180-add_installed_size.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/ipkg-build -+++ b/ipkg-build -@@ -250,6 +250,11 @@ mkdir $tmp_dir - - echo $CONTROL > $tmp_dir/tarX - ( cd $pkg_dir && $TAR $ogargs -X $tmp_dir/tarX -czf $tmp_dir/data.tar.gz . ) -+ -+installed_size=`stat -c "%s" $tmp_dir/data.tar.gz` -+sed -i -e "s/^Installed-Size: .*/Installed-Size: $installed_size/" \ -+ $pkg_dir/$CONTROL/control -+ - ( cd $pkg_dir/$CONTROL && $TAR $ogargs -czf $tmp_dir/control.tar.gz . ) - rm $tmp_dir/tarX - diff --git a/tools/ipkg-utils/patches/190-preserve_permissions.patch b/tools/ipkg-utils/patches/190-preserve_permissions.patch deleted file mode 100644 index 27ba5217b06..00000000000 --- a/tools/ipkg-utils/patches/190-preserve_permissions.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/ipkg-build -+++ b/ipkg-build -@@ -249,7 +249,8 @@ tmp_dir=$dest_dir/IPKG_BUILD.$$ - mkdir $tmp_dir - - echo $CONTROL > $tmp_dir/tarX --( cd $pkg_dir && $TAR $ogargs -X $tmp_dir/tarX -czf $tmp_dir/data.tar.gz . ) -+# Preserve permissions (-p) when creating data.tar.gz as non-root user -+( cd $pkg_dir && $TAR $ogargs -X $tmp_dir/tarX -czpf $tmp_dir/data.tar.gz . ) - - installed_size=`du -b $tmp_dir/data.tar.gz | cut -f1` - sed -i -e "s/^Installed-Size: .*/Installed-Size: $installed_size/" \ diff --git a/tools/isl/Makefile b/tools/isl/Makefile new file mode 100644 index 00000000000..da37437119d --- /dev/null +++ b/tools/isl/Makefile @@ -0,0 +1,27 @@ +# +# Copyright (C) 2009-2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=isl +PKG_VERSION:=0.18 + +PKG_SOURCE_URL:=http://isl.gforge.inria.fr +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_HASH:=0f35051cc030b87c673ac1f187de40e386a1482a0cfdf2c552dd6031b307ddc4 + +HOST_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/host-build.mk + +unexport CFLAGS + +HOST_CONFIGURE_ARGS += \ + --enable-static \ + --disable-shared \ + --with-gmp-prefix=$(STAGING_DIR_HOST) + +$(eval $(call HostBuild)) diff --git a/tools/kernel2minor/Makefile b/tools/kernel2minor/Makefile new file mode 100644 index 00000000000..be730b4df6a --- /dev/null +++ b/tools/kernel2minor/Makefile @@ -0,0 +1,29 @@ +# +# Copyright (C) 2016 adron@yapic.net +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=kernel2minor +PKG_VERSION:=0.25 +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=https://github.com/adron-s/kernel2minor.git +PKG_MIRROR_HASH:=6083c46c2fe0da37bacd04d5d5439c0e2a9d00e58ff47a63acfd5057d2aa2145 +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=1e5a52c7941945f6d64807ebca4a5923ba5466bd +PKG_HASH:=33ca413403a3341af0c9a8e6d9bb58f4ad080a5339e8a8729b83637d35bfaf1b + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Install + $(INSTALL_BIN) $(HOST_BUILD_DIR)/kernel2minor $(STAGING_DIR_HOST)/bin/ +endef + +define Host/Clean + rm -f $(STAGING_DIR_HOST)/bin/kernel2minor +endef + +$(eval $(call HostBuild)) diff --git a/tools/libelf/Makefile b/tools/libelf/Makefile index f38d70d09b1..ab7360ffee1 100644 --- a/tools/libelf/Makefile +++ b/tools/libelf/Makefile @@ -9,12 +9,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libelf PKG_VERSION:=0.8.13 -PKG_MD5SUM:=4136d7b4c04df68b686570afa26988ac +PKG_HASH:=591a9b4ec81c1f2042a97aa60564e0cb79d041c52faa7416acb38bc95bd2c76d PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://www.mr511.de/software/ +HOST_BUILD_PARALLEL:=1 + include $(INCLUDE_DIR)/host-build.mk HOST_CONFIGURE_ARGS += \ @@ -30,7 +32,7 @@ endef define Host/Compile - $(MAKE) -C $(HOST_BUILD_DIR)/lib/ libelf.a + +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR)/lib/ libelf.a endef define Host/Install diff --git a/tools/libressl/Makefile b/tools/libressl/Makefile new file mode 100644 index 00000000000..4c7e8a7b6ec --- /dev/null +++ b/tools/libressl/Makefile @@ -0,0 +1,27 @@ +# +# Copyright (C) 2016-2017 LEDE project +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=libressl +PKG_VERSION:=2.7.2 +PKG_HASH:=917a8779c342177ff3751a2bf955d0262d1d8916a4b408930c45cef326700995 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://mirror.ox.ac.uk/pub/OpenBSD/LibreSSL \ + http://ftp.jaist.ac.jp/pub/OpenBSD/LibreSSL \ + http://ftp.openbsd.org/pub/OpenBSD/LibreSSL + +HOST_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/host-build.mk + +HOST_CONFIGURE_ARGS += --disable-shared +HOST_CFLAGS += $(FPIC) + +$(eval $(call HostBuild)) diff --git a/tools/libtool/Makefile b/tools/libtool/Makefile index 080689b8ac2..dd4a7f63809 100644 --- a/tools/libtool/Makefile +++ b/tools/libtool/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2008 OpenWrt.org +# Copyright (C) 2008-2015 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,17 +7,26 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libtool +PKG_CPE_ID:=cpe:/a:gnu:libtool PKG_VERSION:=2.4 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNU/$(PKG_NAME) -PKG_MD5SUM:=b32b04148ecdd7344abc6fe8bd1bb021 +PKG_HASH:=afcce660d3dc54c63a0a5ba3cf05272239dc3c54bbeba20f6bad250f9dc007ae + +HOST_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/host-build.mk HOST_CONFIGURE_VARS += \ lt_cv_sys_dlsearch_path="" +define Host/Prepare + $(call Host/Prepare/Default) + (cd $(STAGING_DIR_HOST)/share/aclocal/ && rm -f libtool.m4 ltdl.m4 lt~obsolete.m4 ltoptions.m4 ltsugar.m4 ltversion.m4) + (cd $(HOST_BUILD_DIR); $(AM_TOOL_PATHS) ./bootstrap) +endef + define Host/Install $(MAKE) -C $(HOST_BUILD_DIR) install $(SED) 's,\(hardcode_into_libs\)=yes,\1=no,g' $(STAGING_DIR_HOST)/bin/libtool diff --git a/tools/libtool/patches/000-relocatable.patch b/tools/libtool/patches/000-relocatable.patch index c36b806584a..55265fe5332 100644 --- a/tools/libtool/patches/000-relocatable.patch +++ b/tools/libtool/patches/000-relocatable.patch @@ -1,30 +1,62 @@ --- a/libltdl/config/general.m4sh +++ b/libltdl/config/general.m4sh -@@ -53,7 +53,7 @@ test "${ECHO+set}" = set || ECHO=${as_ec +@@ -45,15 +45,22 @@ progpath="$0" + M4SH_VERBATIM([[ + : ${CP="cp -f"} + test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +-: ${EGREP="@EGREP@"} +-: ${FGREP="@FGREP@"} +-: ${GREP="@GREP@"} + : ${LN_S="@LN_S@"} + : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} -: ${SED="@SED@"} -+test "${STAGING_DIR+set}" = set && ${SED="$STAGING_DIR/../host/bin/sed"} || ${SED="@SED@"} ++if test -n "$STAGING_DIR"; then ++ : ${EGREP="$STAGING_DIR/../host/bin/grep -E"} ++ : ${FGREP="$STAGING_DIR/../host/bin/grep -F"} ++ : ${GREP="$STAGING_DIR/../host/bin/grep"} ++ : ${SED="$STAGING_DIR/../host/bin/sed"} ++else ++ : ${EGREP="@EGREP@"} ++ : ${FGREP="@FGREP@"} ++ : ${GREP="@GREP@"} ++ : ${SED="@SED@"} ++fi : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} --- a/libtoolize.in +++ b/libtoolize.in -@@ -334,7 +334,11 @@ test "${ECHO+set}" = set || ECHO=${as_ec +@@ -326,15 +326,22 @@ as_unset=as_fn_unset + + : ${CP="cp -f"} + test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +-: ${EGREP="@EGREP@"} +-: ${FGREP="@FGREP@"} +-: ${GREP="@GREP@"} + : ${LN_S="@LN_S@"} + : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} -: ${SED="@SED@"} +if test -n "$STAGING_DIR"; then ++ : ${EGREP="$STAGING_DIR/../host/bin/grep -E"} ++ : ${FGREP="$STAGING_DIR/../host/bin/grep -F"} ++ : ${GREP="$STAGING_DIR/../host/bin/grep"} + : ${SED="$STAGING_DIR/../host/bin/sed"} +else ++ : ${EGREP="@EGREP@"} ++ : ${FGREP="@FGREP@"} ++ : ${GREP="@GREP@"} + : ${SED="@SED@"} +fi : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} -@@ -2476,10 +2480,17 @@ func_check_macros () +@@ -2476,10 +2483,17 @@ func_check_macros () # Locations for important files: prefix=@prefix@ @@ -83,6 +115,19 @@ _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl +@@ -7509,9 +7508,9 @@ m4_defun([_LT_DECL_EGREP], + [AC_REQUIRE([AC_PROG_EGREP])dnl + AC_REQUIRE([AC_PROG_FGREP])dnl + test -z "$GREP" && GREP=grep +-_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +-_LT_DECL([], [EGREP], [1], [An ERE matcher]) +-_LT_DECL([], [FGREP], [1], [A literal string matcher]) ++_LT_DECL([], [GREP], ["\${STAGING_DIR:-$STAGING_DIR}/../host/bin/grep"], [A grep program that handles long lines]) ++_LT_DECL([], [EGREP], ["\${STAGING_DIR:-$STAGING_DIR}/../host/bin/grep -E"], [An ERE matcher]) ++_LT_DECL([], [FGREP], ["\${STAGING_DIR:-$STAGING_DIR}/../host/bin/grep -F"], [A literal string matcher]) + dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too + AC_SUBST([GREP]) + ]) @@ -7544,9 +7543,8 @@ AC_SUBST([DLLTOOL]) # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], diff --git a/tools/libtool/patches/160-passthrough-ssp.patch b/tools/libtool/patches/160-passthrough-ssp.patch new file mode 100644 index 00000000000..9fad9aa9df7 --- /dev/null +++ b/tools/libtool/patches/160-passthrough-ssp.patch @@ -0,0 +1,12 @@ +diff -ur libtool-2.4.orig/libltdl/config/ltmain.m4sh libtool-2.4/libltdl/config/ltmain.m4sh +--- libtool-2.4.orig/libltdl/config/ltmain.m4sh 2015-06-18 10:46:15.499996979 +0200 ++++ libtool-2.4/libltdl/config/ltmain.m4sh 2015-06-18 10:48:24.686882213 +0200 +@@ -5061,7 +5061,7 @@ + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ +- -O*|-flto*|-fwhopr*|-fuse-linker-plugin) ++ -O*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" diff --git a/tools/libtool/patches/200-openwrt-branding.patch b/tools/libtool/patches/200-openwrt-branding.patch index 56ea8bf2135..dd3e3d6b784 100644 --- a/tools/libtool/patches/200-openwrt-branding.patch +++ b/tools/libtool/patches/200-openwrt-branding.patch @@ -1,6 +1,6 @@ --- a/libltdl/config/general.m4sh +++ b/libltdl/config/general.m4sh -@@ -352,7 +352,7 @@ opt_warning=: +@@ -359,7 +359,7 @@ opt_warning=: # name if it has been set yet. func_echo () { @@ -9,7 +9,7 @@ } # func_verbose arg... -@@ -378,14 +378,14 @@ func_echo_all () +@@ -385,14 +385,14 @@ func_echo_all () # Echo program name prefixed message to standard error. func_error () { @@ -56,7 +56,7 @@ : --- a/libtoolize.in +++ b/libtoolize.in -@@ -637,7 +637,7 @@ opt_warning=: +@@ -640,7 +640,7 @@ opt_warning=: # name if it has been set yet. func_echo () { @@ -65,7 +65,7 @@ } # func_verbose arg... -@@ -663,14 +663,14 @@ func_echo_all () +@@ -666,14 +666,14 @@ func_echo_all () # Echo program name prefixed message to standard error. func_error () { diff --git a/tools/lzma-old/Makefile b/tools/lzma-old/Makefile index 08511b0ec95..5204127a809 100644 --- a/tools/lzma-old/Makefile +++ b/tools/lzma-old/Makefile @@ -11,7 +11,7 @@ PKG_VERSION:=4.32 PKG_SOURCE:=lzma-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=http://downloads.openwrt.org/sources/ -PKG_MD5SUM:=5587d6ac230ad1903d504fc3253f0e42 +PKG_HASH:=49053e4bb5e0646a841d250d9cb81f7714f5fff04a133216c4748163567acc3d HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/lzma-$(PKG_VERSION) @@ -21,7 +21,9 @@ LIB_DIR=$(HOST_BUILD_DIR)/C/7zip/Compress/LZMA_Lib ALONE_DIR=$(HOST_BUILD_DIR)/C/7zip/Compress/LZMA_Alone define Host/Compile + +$(HOST_MAKE_VARS) \ $(MAKE) -C $(LIB_DIR) + +$(HOST_MAKE_VARS) \ $(MAKE) -f makefile.gcc -C $(ALONE_DIR) endef diff --git a/tools/lzma-old/patches/120-add-cflags.patch b/tools/lzma-old/patches/120-add-cflags.patch new file mode 100644 index 00000000000..9022e7cd279 --- /dev/null +++ b/tools/lzma-old/patches/120-add-cflags.patch @@ -0,0 +1,11 @@ +--- a/C/7zip/Compress/LZMA_Lib/makefile ++++ b/C/7zip/Compress/LZMA_Lib/makefile +@@ -2,7 +2,7 @@ PROG = liblzma.a + CXX = g++ -O3 -Wall + AR = ar + RM = rm -f +-CFLAGS = -c -I ../../../ ++CFLAGS += -c -I ../../../ + + OBJS = \ + ZLib.o \ diff --git a/tools/lzma/Makefile b/tools/lzma/Makefile index 4922f8087f6..7d2669e95f3 100644 --- a/tools/lzma/Makefile +++ b/tools/lzma/Makefile @@ -11,7 +11,7 @@ PKG_VERSION:=4.65 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=http://downloads.openwrt.org/sources/ -PKG_MD5SUM:=434e51a018b4c8ef377bf81520a53af0 +PKG_HASH:=dcbdb5f4843eff638e4a5e8be0e2486a3c5483df73c70823618db8e66f609ec2 HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION) diff --git a/tools/lzma/patches/101-move-copyright-to-usage-info.patch b/tools/lzma/patches/101-move-copyright-to-usage-info.patch new file mode 100644 index 00000000000..ec69285d8e6 --- /dev/null +++ b/tools/lzma/patches/101-move-copyright-to-usage-info.patch @@ -0,0 +1,20 @@ +--- a/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp ++++ b/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp +@@ -101,6 +101,8 @@ static const int kNumSwitches = sizeof(k + + static void PrintHelp() + { ++ fprintf(stderr, "\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n"); ++ + fprintf(stderr, "\nUsage: LZMA <e|d> inputFile outputFile [<switches>...]\n" + " e: encode file\n" + " d: decode file\n" +@@ -168,8 +170,6 @@ int main2(int n, const char *args[]) + g_IsNT = IsItWindowsNT(); + #endif + +- fprintf(stderr, "\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n"); +- + if (n == 1) + { + PrintHelp(); diff --git a/tools/m4/Makefile b/tools/m4/Makefile index b838799ab0f..a6d931b0fd5 100644 --- a/tools/m4/Makefile +++ b/tools/m4/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2008 OpenWrt.org +# Copyright (C) 2008-2013 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,15 +7,20 @@ include $(TOPDIR)/rules.mk PKG_NAME:=m4 -PKG_VERSION:=1.4.16 +PKG_CPE_ID:=cpe:/a:gnu:m4 +PKG_VERSION:=1.4.18 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNU/$(PKG_NAME) -PKG_MD5SUM:=a5dfb4f2b7370e9d34293d23fd09b280 -PKG_CAT:=zcat +PKG_HASH:=f2c1e86ca0a404ff281631bdc8377638992744b175afb806e25871a24a934e07 +PKG_CAT:=xzcat + +HOST_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/host-build.mk +HOST_CONFIGURE_VARS += gl_cv_func_strstr_linear=no + define Host/Clean -$(MAKE) -C $(HOST_BUILD_DIR) uninstall $(call Host/Clean/Default) diff --git a/tools/m4/patches/001-fix-macos-vasnprintf.patch b/tools/m4/patches/001-fix-macos-vasnprintf.patch new file mode 100644 index 00000000000..e41315d34ec --- /dev/null +++ b/tools/m4/patches/001-fix-macos-vasnprintf.patch @@ -0,0 +1,25 @@ +--- a/lib/vasnprintf.c ++++ b/lib/vasnprintf.c +@@ -4858,7 +4858,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t * + #endif + *fbp = dp->conversion; + #if USE_SNPRINTF +-# if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) ++# if ! (((__GLIBC__ > 2 \ ++ || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \ ++ && !defined __UCLIBC__) \ ++ || (defined __APPLE__ && defined __MACH__) \ ++ || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) + fbp[1] = '%'; + fbp[2] = 'n'; + fbp[3] = '\0'; +@@ -4872,6 +4876,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t * + in format strings in writable memory may crash the program + (if compiled with _FORTIFY_SOURCE=2), so we should avoid it + in this situation. */ ++ /* macOS 10.13 High Sierra behaves like glibc with ++ _FORTIFY_SOURCE=2, and older macOS releases ++ presumably do not need %n. */ + /* On native Windows systems (such as mingw), we can avoid using + %n because: + - Although the gl_SNPRINTF_TRUNCATION_C99 test fails, diff --git a/tools/m4/patches/010-glibc-change-work-around.patch b/tools/m4/patches/010-glibc-change-work-around.patch new file mode 100644 index 00000000000..0ef6216965c --- /dev/null +++ b/tools/m4/patches/010-glibc-change-work-around.patch @@ -0,0 +1,118 @@ +Subject: Workaround change in glibc + +Temporary workaround to compile with glibc 2.28, which +deprecated some constants + +Taken from the rpms/m4 Fedora repository, commit 814d5921 +(Work around change in glibc) + +Original filename: m4-1.4.18-glibc-change-work-around.patch + +--- a/lib/stdio-impl.h ++++ b/lib/stdio-impl.h +@@ -18,6 +18,12 @@ + the same implementation of stdio extension API, except that some fields + have different naming conventions, or their access requires some casts. */ + ++/* Glibc 2.28 made _IO_IN_BACKUP private. For now, work around this ++ problem by defining it ourselves. FIXME: Do not rely on glibc ++ internals. */ ++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN ++# define _IO_IN_BACKUP 0x100 ++#endif + + /* BSD stdio derived implementations. */ + +--- a/lib/fflush.c ++++ b/lib/fflush.c +@@ -33,7 +33,7 @@ + #undef fflush + + +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + + /* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */ + static void +@@ -72,7 +72,7 @@ clear_ungetc_buffer (FILE *fp) + + #endif + +-#if ! (defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */) ++#if ! (defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */) + + # if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */ +@@ -148,7 +148,7 @@ rpl_fflush (FILE *stream) + if (stream == NULL || ! freading (stream)) + return fflush (stream); + +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + + clear_ungetc_buffer_preserving_position (stream); + +--- a/lib/fpending.c ++++ b/lib/fpending.c +@@ -32,7 +32,7 @@ __fpending (FILE *fp) + /* Most systems provide FILE as a struct and the necessary bitmask in + <stdio.h>, because they need it for implementing getc() and putc() as + fast macros. */ +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + return fp->_IO_write_ptr - fp->_IO_write_base; + #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */ +--- a/lib/fpurge.c ++++ b/lib/fpurge.c +@@ -62,7 +62,7 @@ fpurge (FILE *fp) + /* Most systems provide FILE as a struct and the necessary bitmask in + <stdio.h>, because they need it for implementing getc() and putc() as + fast macros. */ +-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + fp->_IO_read_end = fp->_IO_read_ptr; + fp->_IO_write_ptr = fp->_IO_write_base; + /* Avoid memory leak when there is an active ungetc buffer. */ +--- a/lib/freadahead.c ++++ b/lib/freadahead.c +@@ -25,7 +25,7 @@ + size_t + freadahead (FILE *fp) + { +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + if (fp->_IO_write_ptr > fp->_IO_write_base) + return 0; + return (fp->_IO_read_end - fp->_IO_read_ptr) +--- a/lib/freading.c ++++ b/lib/freading.c +@@ -31,7 +31,7 @@ freading (FILE *fp) + /* Most systems provide FILE as a struct and the necessary bitmask in + <stdio.h>, because they need it for implementing getc() and putc() as + fast macros. */ +-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + return ((fp->_flags & _IO_NO_WRITES) != 0 + || ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0 + && fp->_IO_read_base != NULL)); +--- a/lib/fseeko.c ++++ b/lib/fseeko.c +@@ -47,7 +47,7 @@ fseeko (FILE *fp, off_t offset, int when + #endif + + /* These tests are based on fpurge.c. */ +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + if (fp->_IO_read_end == fp->_IO_read_ptr + && fp->_IO_write_ptr == fp->_IO_write_base + && fp->_IO_save_base == NULL) +@@ -123,7 +123,7 @@ fseeko (FILE *fp, off_t offset, int when + return -1; + } + +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + fp->_flags &= ~_IO_EOF_SEEN; + fp->_offset = pos; + #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ diff --git a/tools/make-ext4fs/Makefile b/tools/make-ext4fs/Makefile new file mode 100644 index 00000000000..f67ab6e5b58 --- /dev/null +++ b/tools/make-ext4fs/Makefile @@ -0,0 +1,28 @@ +# +# Copyright (C) 2015 OpenWrt.org +# Copyright (C) 2016 LEDE project +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=make-ext4fs + +PKG_SOURCE_URL=$(PROJECT_GIT)/project/make_ext4fs.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2016-08-14 +PKG_SOURCE_VERSION:=484903e4332be6c317f531b008cb2a841a18c506 +PKG_MIRROR_HASH:=d7ccd5e426b1d15331ff000a37dc15161f6eef594453e970fd584fcde5a25075 + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Install + $(INSTALL_BIN) $(HOST_BUILD_DIR)/make_ext4fs $(STAGING_DIR_HOST)/bin/ +endef + +define Host/Clean + rm -f $(STAGING_DIR_HOST)/bin/make_ext4fs +endef + +$(eval $(call HostBuild)) diff --git a/tools/make-ext4fs/patches/100-add-ldflags.patch b/tools/make-ext4fs/patches/100-add-ldflags.patch new file mode 100644 index 00000000000..d9ce47bb809 --- /dev/null +++ b/tools/make-ext4fs/patches/100-add-ldflags.patch @@ -0,0 +1,11 @@ +--- a/Makefile ++++ b/Makefile +@@ -27,7 +27,7 @@ OBJ := \ + $(CC) $(CFLAGS) -c -o $@ $^ + + make_ext4fs: $(OBJ) libsparse/libsparse.a +- $(CC) -o $@ $^ $(ZLIB) ++ $(CC) $(LDFLAGS)-o $@ $^ $(ZLIB) + + libsparse/libsparse.a: + $(MAKE) -C libsparse/ libsparse.a diff --git a/tools/missing-macros/Makefile b/tools/missing-macros/Makefile index ab50a674682..e4b69b3875c 100644 --- a/tools/missing-macros/Makefile +++ b/tools/missing-macros/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2010-2011 OpenWrt.org +# Copyright (C) 2010-2015 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -21,6 +21,8 @@ endef define Host/Install $(INSTALL_DIR) $(STAGING_DIR_HOST)/share/aclocal $(INSTALL_DATA) ./src/m4/*.m4 $(STAGING_DIR_HOST)/share/aclocal/ + $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin + $(INSTALL_BIN) ./src/bin/* $(STAGING_DIR_HOST)/bin/ endef $(eval $(call HostBuild)) diff --git a/tools/missing-macros/src/bin/help2man b/tools/missing-macros/src/bin/help2man new file mode 100755 index 00000000000..6cbec57c50f --- /dev/null +++ b/tools/missing-macros/src/bin/help2man @@ -0,0 +1,29 @@ +#!/usr/bin/env perl + +use strict; +use Getopt::Long; + +my $output; +my $version; + +Getopt::Long::Configure('pass_through'); +Getopt::Long::GetOptions( + 'output=s' => \$output, + 'version' => \$version +); + +if ($version) +{ + printf "OpenWrt help2man 1.40.10\n"; + exit 0; +} +elsif ($output) +{ + open O, "> $output" || die "Unable to open $output: $!\n"; + print O "Dummy man page.\n"; + close O; +} +else +{ + print O "Dummy man page.\n"; +} diff --git a/tools/missing-macros/src/bin/makeinfo b/tools/missing-macros/src/bin/makeinfo new file mode 100755 index 00000000000..e163cba0843 --- /dev/null +++ b/tools/missing-macros/src/bin/makeinfo @@ -0,0 +1,112 @@ +#!/usr/bin/env perl + +use strict; +use Getopt::Long; + +my $output; +my $version; +my $docbook; +my $html; +my $xml; +my $plaintext; +my $no_split; +my $no_headers; + +Getopt::Long::Configure('pass_through'); +Getopt::Long::GetOptions( + 'output=s' => \$output, + 'version' => \$version, + 'no-split' => \$no_split, + 'no-headers' => \$no_headers, + 'docbook' => \$docbook, + 'html' => \$html, + 'xml' => \$xml, + 'plaintext' => \$plaintext +); + +if ($version) +{ + print "makeinfo (OpenWrt stub) 4.13\n"; + exit 0; +} + + +sub output_filename +{ + my $path = shift || return; + my $name = $path; + my $setfile; + + if (open F, "< $path") + { + while (defined(my $line = readline F)) + { + if ($line =~ /\@setfilename\s+(\S+)/) + { + $setfile = $1; + $setfile =~ s!^.+/!!; + last; + } + } + + close F; + } + + $name =~ s!^.+/!!; + $name =~ s!\.[^.]+$!!; + + if ($html) + { + $setfile =~ s!\.[^.]+$!! if $setfile; + + if ($no_split) + { + return $setfile ? "$setfile.html" : "$name.html" unless $output; + return $output; + } + + return $setfile ? "$setfile/index.html" : "$name/index.html" unless $output; + return "$output/index.html"; + } + elsif ($xml || $docbook) + { + $setfile =~ s!\.[^.]+$!! if $setfile; + + return $setfile ? "$setfile.xml" : "$name.info" unless $output; + return $output; + } + elsif ($plaintext) + { + return ($output || "-"); + } + + return ($output || $setfile || "$name.info"); +} + +foreach my $arg (@ARGV) +{ + next unless -f $arg; + + my $out = output_filename($arg); + if ($out =~ m!^(.+/)[^/]+$!) + { + system("mkdir", "-p", $1); + } + + my $fd = \*STDOUT; + if ($out ne "-" && !$no_headers) + { + open $fd, "> $out" || die "Can't open $out: $!\n"; + } + + if ($html || $xml || $docbook) + { + print $fd "<!-- Dummy output for $arg -->\n"; + } + else + { + print $fd "Dummy output for $arg\n"; + } + + close $fd; +} diff --git a/tools/missing-macros/src/m4/esd.m4 b/tools/missing-macros/src/m4/esd.m4 deleted file mode 100644 index bb07d0f1755..00000000000 --- a/tools/missing-macros/src/m4/esd.m4 +++ /dev/null @@ -1,196 +0,0 @@ -# esd.m4 serial 1 (libmikmod-3.1.12) -# Configure paths for ESD -# Manish Singh 98-9-30 -# stolen back from Frank Belew -# stolen from Manish Singh -# Shamelessly stolen from Owen Taylor - -dnl AM_PATH_ESD([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -dnl Test for ESD, and define ESD_CFLAGS and ESD_LIBS -dnl -AC_DEFUN([AM_PATH_ESD], -[dnl -dnl Get the cflags and libraries from the esd-config script -dnl -AC_ARG_WITH(esd-prefix,[ --with-esd-prefix=PFX Prefix where ESD is installed (optional)], - esd_prefix="$withval", esd_prefix="") -AC_ARG_WITH(esd-exec-prefix,[ --with-esd-exec-prefix=PFX Exec prefix where ESD is installed (optional)], - esd_exec_prefix="$withval", esd_exec_prefix="") -AC_ARG_ENABLE(esdtest, [ --disable-esdtest Do not try to compile and run a test ESD program], - , enable_esdtest=yes) - - if test x$esd_exec_prefix != x ; then - esd_args="$esd_args --exec-prefix=$esd_exec_prefix" - if test x${ESD_CONFIG+set} != xset ; then - ESD_CONFIG=$esd_exec_prefix/bin/esd-config - fi - fi - if test x$esd_prefix != x ; then - esd_args="$esd_args --prefix=$esd_prefix" - if test x${ESD_CONFIG+set} != xset ; then - ESD_CONFIG=$esd_prefix/bin/esd-config - fi - fi - - AC_PATH_PROG(ESD_CONFIG, esd-config, no) - min_esd_version=ifelse([$1], ,0.2.7,$1) - AC_MSG_CHECKING(for ESD - version >= $min_esd_version) - no_esd="" - if test "$ESD_CONFIG" = "no" ; then - no_esd=yes - else - AC_LANG_SAVE - AC_LANG_C - ESD_CFLAGS=`$ESD_CONFIG $esdconf_args --cflags` - ESD_LIBS=`$ESD_CONFIG $esdconf_args --libs` - - esd_major_version=`$ESD_CONFIG $esd_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - esd_minor_version=`$ESD_CONFIG $esd_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - esd_micro_version=`$ESD_CONFIG $esd_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - if test "x$enable_esdtest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $ESD_CFLAGS" - LIBS="$LIBS $ESD_LIBS" -dnl -dnl Now check if the installed ESD is sufficiently new. (Also sanity -dnl checks the results of esd-config to some extent -dnl - rm -f conf.esdtest - AC_TRY_RUN([ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <esd.h> - -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - -int main () -{ - int major, minor, micro; - char *tmp_version; - - system ("touch conf.esdtest"); - - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_esd_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { - printf("%s, bad version string\n", "$min_esd_version"); - exit(1); - } - - if (($esd_major_version > major) || - (($esd_major_version == major) && ($esd_minor_version > minor)) || - (($esd_major_version == major) && ($esd_minor_version == minor) && ($esd_micro_version >= micro))) - { - return 0; - } - else - { - printf("\n*** 'esd-config --version' returned %d.%d.%d, but the minimum version\n", $esd_major_version, $esd_minor_version, $esd_micro_version); - printf("*** of ESD required is %d.%d.%d. If esd-config is correct, then it is\n", major, minor, micro); - printf("*** best to upgrade to the required version.\n"); - printf("*** If esd-config was wrong, set the environment variable ESD_CONFIG\n"); - printf("*** to point to the correct copy of esd-config, and remove the file\n"); - printf("*** config.cache before re-running configure\n"); - return 1; - } -} - -],, no_esd=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - AC_LANG_RESTORE - fi - fi - if test "x$no_esd" = x ; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - AC_MSG_RESULT(no) - if test "$ESD_CONFIG" = "no" ; then - echo "*** The esd-config script installed by ESD could not be found" - echo "*** If ESD was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the ESD_CONFIG environment variable to the" - echo "*** full path to esd-config." - else - if test -f conf.esdtest ; then - : - else - echo "*** Could not run ESD test program, checking why..." - CFLAGS="$CFLAGS $ESD_CFLAGS" - LIBS="$LIBS $ESD_LIBS" - AC_LANG_SAVE - AC_LANG_C - AC_TRY_LINK([ -#include <stdio.h> -#include <esd.h> -], [ return 0; ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding ESD or finding the wrong" - echo "*** version of ESD. If it is not finding ESD, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means ESD was incorrectly installed" - echo "*** or that you have moved ESD since it was installed. In the latter case, you" - echo "*** may want to edit the esd-config script: $ESD_CONFIG" ]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - AC_LANG_RESTORE - fi - fi - ESD_CFLAGS="" - ESD_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(ESD_CFLAGS) - AC_SUBST(ESD_LIBS) - rm -f conf.esdtest -]) - -dnl AM_ESD_SUPPORTS_MULTIPLE_RECORD([ACTION-IF-SUPPORTS [, ACTION-IF-NOT-SUPPORTS]]) -dnl Test, whether esd supports multiple recording clients (version >=0.2.21) -dnl -AC_DEFUN([AM_ESD_SUPPORTS_MULTIPLE_RECORD], -[dnl - AC_MSG_NOTICE([whether installed esd version supports multiple recording clients]) - ac_save_ESD_CFLAGS="$ESD_CFLAGS" - ac_save_ESD_LIBS="$ESD_LIBS" - AM_PATH_ESD(0.2.21, - ifelse([$1], , [ - AM_CONDITIONAL(ESD_SUPPORTS_MULTIPLE_RECORD, true) - AC_DEFINE(ESD_SUPPORTS_MULTIPLE_RECORD, 1, - [Define if you have esound with support of multiple recording clients.])], - [$1]), - ifelse([$2], , [AM_CONDITIONAL(ESD_SUPPORTS_MULTIPLE_RECORD, false)], [$2]) - if test "x$ac_save_ESD_CFLAGS" != x ; then - ESD_CFLAGS="$ac_save_ESD_CFLAGS" - fi - if test "x$ac_save_ESD_LIBS" != x ; then - ESD_LIBS="$ac_save_ESD_LIBS" - fi - ) -]) - diff --git a/tools/missing-macros/src/m4/xaw.m4 b/tools/missing-macros/src/m4/xaw.m4 deleted file mode 100644 index 60404ae8c28..00000000000 --- a/tools/missing-macros/src/m4/xaw.m4 +++ /dev/null @@ -1,65 +0,0 @@ -dnl Copyright 2005 Red Hat, Inc -dnl -dnl Permission to use, copy, modify, distribute, and sell this software and its -dnl documentation for any purpose is hereby granted without fee, provided that -dnl the above copyright notice appear in all copies and that both that -dnl copyright notice and this permission notice appear in supporting -dnl documentation. -dnl -dnl The above copyright notice and this permission notice shall be included -dnl in all copies or substantial portions of the Software. -dnl -dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -dnl IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -dnl OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -dnl ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -dnl OTHER DEALINGS IN THE SOFTWARE. -dnl -dnl Except as contained in this notice, the name of the copyright holders shall -dnl not be used in advertising or otherwise to promote the sale, use or -dnl other dealings in this Software without prior written authorization -dnl from the copyright holders. -dnl - -# XAW_CHECK_XPRINT_SUPPORT() -# -------------------------- -# Adds --enable/disable-xprint and selects the appropriate version of the Xaw -# library. If neither --enable-xprint nor --disable-xprint are given, -# the presence of an Xaw with Xprint support will be auto detected - -AC_DEFUN([XAW_CHECK_XPRINT_SUPPORT],[ - AC_ARG_ENABLE(xprint, AC_HELP_STRING([--enable-xprint], [Enable XPrint support]), - [use_xprint=$enableval],[use_xprint=auto]) - if test "x$use_xprint" = "xyes"; then - TMP_CHECK1=xaw8 - TMP_CHECK2= - xaw_use_xprint=yes - elif test "x$use_xprint" = "xno"; then - TMP_CHECK1=xaw7 - TMP_CHECK2= - xaw_use_xprint=no - else - TMP_CHECK1=xaw8 - TMP_CHECK2=xaw7 - xaw_use_xprint=yes - fi - - PKG_CHECK_MODULES(TMP_XAW, $TMP_CHECK1, success=yes, success=no) - if [[ ! -z $TMP_CHECK2 ]] ; then - if test $success = no ; then - PKG_CHECK_MODULES(TMP_XAW, $TMP_CHECK2, success=yes, success=no) - xaw_use_xprint=no - fi - fi - - if test "x$success" = "xyes"; then - $1_CFLAGS=$TMP_XAW_CFLAGS - $1_LIBS=$TMP_XAW_LIBS - - AM_CONDITIONAL([XAW_USE_XPRINT], [test "x$xaw_use_xprint" = "xyes"]) - else - AC_MSG_ERROR([No suitable version of Xaw found]) - fi -]) diff --git a/tools/missing-macros/src/m4/xmms.m4 b/tools/missing-macros/src/m4/xmms.m4 deleted file mode 100644 index 8aeaad817d3..00000000000 --- a/tools/missing-macros/src/m4/xmms.m4 +++ /dev/null @@ -1,149 +0,0 @@ -# CFLAGS and library paths for XMMS -# written 15 December 1999 by Ben Gertzfield <che@debian.org> - -dnl Usage: -dnl AM_PATH_XMMS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -dnl -dnl Example: -dnl AM_PATH_XMMS(0.9.5.1, , AC_MSG_ERROR([*** XMMS >= 0.9.5.1 not installed - please install first ***])) -dnl -dnl Defines XMMS_CFLAGS, XMMS_LIBS, XMMS_DATA_DIR, XMMS_PLUGIN_DIR, -dnl XMMS_VISUALIZATION_PLUGIN_DIR, XMMS_INPUT_PLUGIN_DIR, -dnl XMMS_OUTPUT_PLUGIN_DIR, XMMS_GENERAL_PLUGIN_DIR, XMMS_EFFECT_PLUGIN_DIR, -dnl and XMMS_VERSION for your plugin pleasure. -dnl - -dnl XMMS_TEST_VERSION(AVAILABLE-VERSION, NEEDED-VERSION [, ACTION-IF-OKAY [, ACTION-IF-NOT-OKAY]]) -AC_DEFUN([XMMS_TEST_VERSION], [ - -# Determine which version number is greater. Prints 2 to stdout if -# the second number is greater, 1 if the first number is greater, -# 0 if the numbers are equal. - -# Written 15 December 1999 by Ben Gertzfield <che@debian.org> -# Revised 15 December 1999 by Jim Monty <monty@primenet.com> - - AC_PROG_AWK - xmms_got_version=[` $AWK ' \ -BEGIN { \ - print vercmp(ARGV[1], ARGV[2]); \ -} \ - \ -function vercmp(ver1, ver2, ver1arr, ver2arr, \ - ver1len, ver2len, \ - ver1int, ver2int, len, i, p) { \ - \ - ver1len = split(ver1, ver1arr, /\./); \ - ver2len = split(ver2, ver2arr, /\./); \ - \ - len = ver1len > ver2len ? ver1len : ver2len; \ - \ - for (i = 1; i <= len; i++) { \ - p = 1000 ^ (len - i); \ - ver1int += ver1arr[i] * p; \ - ver2int += ver2arr[i] * p; \ - } \ - \ - if (ver1int < ver2int) \ - return 2; \ - else if (ver1int > ver2int) \ - return 1; \ - else \ - return 0; \ -}' $1 $2`] - - if test $xmms_got_version -eq 2; then # failure - ifelse([$4], , :, $4) - else # success! - ifelse([$3], , :, $3) - fi -]) - -AC_DEFUN([AM_PATH_XMMS], -[ -AC_ARG_WITH(xmms-prefix,[ --with-xmms-prefix=PFX Prefix where XMMS is installed (optional)], - xmms_config_prefix="$withval", xmms_config_prefix="") -AC_ARG_WITH(xmms-exec-prefix,[ --with-xmms-exec-prefix=PFX Exec prefix where XMMS is installed (optional)], - xmms_config_exec_prefix="$withval", xmms_config_exec_prefix="") - -if test x$xmms_config_exec_prefix != x; then - xmms_config_args="$xmms_config_args --exec-prefix=$xmms_config_exec_prefix" - if test x${XMMS_CONFIG+set} != xset; then - XMMS_CONFIG=$xmms_config_exec_prefix/bin/xmms-config - fi -fi - -if test x$xmms_config_prefix != x; then - xmms_config_args="$xmms_config_args --prefix=$xmms_config_prefix" - if test x${XMMS_CONFIG+set} != xset; then - XMMS_CONFIG=$xmms_config_prefix/bin/xmms-config - fi -fi - -AC_PATH_PROG(XMMS_CONFIG, xmms-config, no) -min_xmms_version=ifelse([$1], ,0.9.5.1, $1) - -if test "$XMMS_CONFIG" = "no"; then - no_xmms=yes -else - XMMS_CFLAGS=`$XMMS_CONFIG $xmms_config_args --cflags` - XMMS_LIBS=`$XMMS_CONFIG $xmms_config_args --libs` - XMMS_VERSION=`$XMMS_CONFIG $xmms_config_args --version` - XMMS_DATA_DIR=`$XMMS_CONFIG $xmms_config_args --data-dir` - XMMS_PLUGIN_DIR=`$XMMS_CONFIG $xmms_config_args --plugin-dir` - XMMS_VISUALIZATION_PLUGIN_DIR=`$XMMS_CONFIG $xmms_config_args \ - --visualization-plugin-dir` - XMMS_INPUT_PLUGIN_DIR=`$XMMS_CONFIG $xmms_config_args --input-plugin-dir` - XMMS_OUTPUT_PLUGIN_DIR=`$XMMS_CONFIG $xmms_config_args --output-plugin-dir` - XMMS_EFFECT_PLUGIN_DIR=`$XMMS_CONFIG $xmms_config_args --effect-plugin-dir` - XMMS_GENERAL_PLUGIN_DIR=`$XMMS_CONFIG $xmms_config_args --general-plugin-dir` - - XMMS_TEST_VERSION($XMMS_VERSION, $min_xmms_version, ,no_xmms=version) -fi - -AC_MSG_CHECKING(for XMMS - version >= $min_xmms_version) - -if test "x$no_xmms" = x; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) -else - AC_MSG_RESULT(no) - - if test "$XMMS_CONFIG" = "no" ; then - echo "*** The xmms-config script installed by XMMS could not be found." - echo "*** If XMMS was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the XMMS_CONFIG environment variable to the" - echo "*** full path to xmms-config." - else - if test "$no_xmms" = "version"; then - echo "*** An old version of XMMS, $XMMS_VERSION, was found." - echo "*** You need a version of XMMS newer than $min_xmms_version." - echo "*** The latest version of XMMS is always available from" - echo "*** http://www.xmms.org/" - echo "***" - - echo "*** If you have already installed a sufficiently new version, this error" - echo "*** probably means that the wrong copy of the xmms-config shell script is" - echo "*** being found. The easiest way to fix this is to remove the old version" - echo "*** of XMMS, but you can also set the XMMS_CONFIG environment to point to the" - echo "*** correct copy of xmms-config. (In this case, you will have to" - echo "*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf" - echo "*** so that the correct libraries are found at run-time)" - fi - fi - XMMS_CFLAGS="" - XMMS_LIBS="" - ifelse([$3], , :, [$3]) -fi -AC_SUBST(XMMS_CFLAGS) -AC_SUBST(XMMS_LIBS) -AC_SUBST(XMMS_VERSION) -AC_SUBST(XMMS_DATA_DIR) -AC_SUBST(XMMS_PLUGIN_DIR) -AC_SUBST(XMMS_VISUALIZATION_PLUGIN_DIR) -AC_SUBST(XMMS_INPUT_PLUGIN_DIR) -AC_SUBST(XMMS_OUTPUT_PLUGIN_DIR) -AC_SUBST(XMMS_GENERAL_PLUGIN_DIR) -AC_SUBST(XMMS_EFFECT_PLUGIN_DIR) -]) - diff --git a/tools/mkimage/Makefile b/tools/mkimage/Makefile index 2ea1123c265..d0ff5f7e370 100644 --- a/tools/mkimage/Makefile +++ b/tools/mkimage/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006-2011 OpenWrt.org +# Copyright (C) 2006-2014 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,29 +7,42 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mkimage -PKG_VERSION:=2011.06 +PKG_VERSION:=2018.03 PKG_SOURCE:=u-boot-$(PKG_VERSION).tar.bz2 -PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot -PKG_MD5SUM:=0cc5026aad02f218a9b9ac56b301c97a -PKG_CAT:=bzcat +PKG_SOURCE_URL:=\ + http://mirror2.openwrt.org/sources \ + ftp://ftp.denx.de/pub/u-boot +PKG_HASH:=7e7477534409d5368eb1371ffde6820f0f79780a1a1f676161c48442cb303dfd HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/u-boot-$(PKG_VERSION) include $(INCLUDE_DIR)/host-build.mk +define Host/Prepare + $(Host/Prepare/Default) + mkdir -p $(HOST_BUILD_DIR)/include/config + touch $(HOST_BUILD_DIR)/include/config/auto.conf +endef + define Host/Compile - rm -f $(HOST_BUILD_DIR)/tools/.depend - touch $(HOST_BUILD_DIR)/include/config.h - $(MAKE) -C $(HOST_BUILD_DIR) BUILD_DIR= BIN_FILES-y="mkimage" tools + $(MAKE) -C $(HOST_BUILD_DIR) \ + HOSTCFLAGS="$(HOST_CFLAGS)" \ + HOSTLDFLAGS="$(HOST_LDFLAGS)" \ + no-dot-config-targets=tools-only \ + CONFIG_MKIMAGE_DTC_PATH=dtc \ + CONFIG_FIT_SIGNATURE=y \ + tools-only endef define Host/Install $(CP) $(HOST_BUILD_DIR)/tools/mkimage $(STAGING_DIR_HOST)/bin/ + $(CP) $(HOST_BUILD_DIR)/tools/mkenvimage $(STAGING_DIR_HOST)/bin/ endef define Host/Clean rm -f $(STAGING_DIR_HOST)/bin/mkimage + rm -f $(STAGING_DIR_HOST)/bin/mkenvimage endef $(eval $(call HostBuild)) diff --git a/tools/mkimage/patches/010-freebsd-ulong-fix.patch b/tools/mkimage/patches/010-freebsd-ulong-fix.patch index 32fa0745339..7d891657f8a 100644 --- a/tools/mkimage/patches/010-freebsd-ulong-fix.patch +++ b/tools/mkimage/patches/010-freebsd-ulong-fix.patch @@ -1,6 +1,6 @@ --- a/include/image.h +++ b/include/image.h -@@ -50,6 +50,10 @@ +@@ -51,6 +51,10 @@ struct lmb; #endif /* USE_HOSTCC */ @@ -8,6 +8,6 @@ +#define ulong unsigned long +#endif + - #if defined(CONFIG_FIT) - #include <fdt.h> - #include <libfdt.h> + #if IMAGE_ENABLE_FIT + #include <hash.h> + #include <linux/libfdt.h> diff --git a/tools/mkimage/patches/020-darwin-10_7-getline-fix.patch b/tools/mkimage/patches/020-darwin-10_7-getline-fix.patch deleted file mode 100644 index ff1ae807da0..00000000000 --- a/tools/mkimage/patches/020-darwin-10_7-getline-fix.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/tools/os_support.h -+++ b/tools/os_support.h -@@ -28,7 +28,7 @@ - #include "mingw_support.h" - #endif - --#ifdef __APPLE__ -+#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L - #include "getline.h" - #endif - ---- a/tools/os_support.c -+++ b/tools/os_support.c -@@ -23,6 +23,7 @@ - #ifdef __MINGW32__ - #include "mingw_support.c" - #endif --#ifdef __APPLE__ -+ -+#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L - #include "getline.c" - #endif diff --git a/tools/mkimage/patches/020-include_compile_fix.patch b/tools/mkimage/patches/020-include_compile_fix.patch new file mode 100644 index 00000000000..276cae0cb16 --- /dev/null +++ b/tools/mkimage/patches/020-include_compile_fix.patch @@ -0,0 +1,10 @@ +--- a/include/u-boot/rsa-checksum.h ++++ b/include/u-boot/rsa-checksum.h +@@ -7,7 +7,6 @@ + #ifndef _RSA_CHECKSUM_H + #define _RSA_CHECKSUM_H + +-#include <errno.h> + #include <image.h> + #include <u-boot/sha1.h> + #include <u-boot/sha256.h> diff --git a/tools/mkimage/patches/030-allow-to-use-different-magic.patch b/tools/mkimage/patches/030-allow-to-use-different-magic.patch index 31a9065f3f0..c6de9a0aaf6 100644 --- a/tools/mkimage/patches/030-allow-to-use-different-magic.patch +++ b/tools/mkimage/patches/030-allow-to-use-different-magic.patch @@ -1,48 +1,65 @@ --- a/tools/mkimage.c +++ b/tools/mkimage.c -@@ -37,6 +37,7 @@ struct mkimage_params params = { +@@ -21,6 +21,7 @@ static struct image_tool_params params = .arch = IH_ARCH_PPC, .type = IH_TYPE_KERNEL, .comp = IH_COMP_GZIP, + .magic = IH_MAGIC, .dtc = MKIMAGE_DEFAULT_DTC_OPTIONS, .imagename = "", - }; -@@ -180,6 +181,16 @@ main (int argc, char **argv) - genimg_get_comp_id (*++argv)) < 0) - usage (); - goto NXTARG; -+ case 'M': -+ if (--argc <=0) -+ usage (); -+ params.magic = strtoul (*++argv, &ptr, 16); -+ if (*ptr) { -+ fprintf (stderr, -+ "%s: invalid magic %s\n", -+ params.cmdname, *argv); -+ } -+ goto NXTARG; - case 'D': - if (--argc <= 0) - usage (); -@@ -580,12 +591,13 @@ usage () - fprintf (stderr, "Usage: %s -l image\n" + .imagename2 = "", +@@ -77,11 +78,12 @@ static void usage(const char *msg) " -l ==> list image header information\n", params.cmdname); -- fprintf (stderr, " %s [-x] -A arch -O os -T type -C comp " -+ fprintf (stderr, " %s [-x] -A arch -O os -T type -C comp -M magic " - "-a addr -e ep -n name -d data_file[:data_file...] image\n" - " -A ==> set architecture to 'arch'\n" - " -O ==> set operating system to 'os'\n" - " -T ==> set image type to 'type'\n" - " -C ==> set compression type 'comp'\n" -+ " -M ==> set image magic to 'magic'\n" - " -a ==> set load address to 'addr' (hex)\n" - " -e ==> set entry point to 'ep' (hex)\n" - " -n ==> set image name to 'name'\n" ---- a/tools/mkimage.h -+++ b/tools/mkimage.h -@@ -64,6 +64,7 @@ struct mkimage_params { + fprintf(stderr, +- " %s [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image\n" ++ " %s [-x] -A arch -O os -T type -C comp -M magic -a addr -e ep -n name -d data_file[:data_file...] image\n" + " -A ==> set architecture to 'arch'\n" + " -O ==> set operating system to 'os'\n" + " -T ==> set image type to 'type'\n" + " -C ==> set compression type 'comp'\n" ++ " -M ==> set image magic to 'magic'\n" + " -a ==> set load address to 'addr' (hex)\n" + " -e ==> set entry point to 'ep' (hex)\n" + " -n ==> set image name to 'name'\n" +@@ -144,7 +146,7 @@ static void process_args(int argc, char + int opt; + + while ((opt = getopt(argc, argv, +- "a:A:b:c:C:d:D:e:Ef:Fk:i:K:ln:N:p:O:rR:qsT:vVx")) != -1) { ++ "a:A:b:c:C:d:D:e:Ef:Fk:i:K:lM:n:N:p:O:rR:qsT:vVx")) != -1) { + switch (opt) { + case 'a': + params.addr = strtoull(optarg, &ptr, 16); +@@ -222,6 +224,14 @@ static void process_args(int argc, char + case 'l': + params.lflag = 1; + break; ++ case 'M': ++ params.magic = strtoull(optarg, &ptr, 16); ++ if (*ptr) { ++ fprintf(stderr, "%s: invalid magic %s\n", ++ params.cmdname, optarg); ++ exit(EXIT_FAILURE); ++ } ++ break; + case 'n': + params.imagename = optarg; + break; +--- a/tools/default_image.c ++++ b/tools/default_image.c +@@ -106,7 +106,7 @@ static void image_set_header(void *ptr, + imagesize = sbuf->st_size - sizeof(image_header_t); + + /* Build new header */ +- image_set_magic(hdr, IH_MAGIC); ++ image_set_magic(hdr, params->magic); + image_set_time(hdr, time); + image_set_size(hdr, imagesize); + image_set_load(hdr, params->addr); +--- a/tools/imagetool.h ++++ b/tools/imagetool.h +@@ -54,6 +54,7 @@ struct image_tool_params { int arch; int type; int comp; @@ -50,14 +67,3 @@ char *dtc; unsigned int addr; unsigned int ep; ---- a/tools/default_image.c -+++ b/tools/default_image.c -@@ -110,7 +110,7 @@ static void image_set_header (void *ptr, - sbuf->st_size - sizeof(image_header_t)); - - /* Build new header */ -- image_set_magic (hdr, IH_MAGIC); -+ image_set_magic (hdr, params->magic); - image_set_time (hdr, sbuf->st_mtime); - image_set_size (hdr, sbuf->st_size - sizeof(image_header_t)); - image_set_load (hdr, params->addr); diff --git a/tools/mkimage/patches/050-image_h_portability.patch b/tools/mkimage/patches/050-image_h_portability.patch new file mode 100644 index 00000000000..dabab399080 --- /dev/null +++ b/tools/mkimage/patches/050-image_h_portability.patch @@ -0,0 +1,31 @@ +--- a/include/image.h ++++ b/include/image.h +@@ -17,7 +17,6 @@ + #define __IMAGE_H__ + + #include "compiler.h" +-#include <asm/byteorder.h> + + /* Define this to avoid #ifdefs later on */ + struct lmb; +@@ -308,13 +307,13 @@ enum { + * all data in network byte order (aka natural aka bigendian). + */ + typedef struct image_header { +- __be32 ih_magic; /* Image Header Magic Number */ +- __be32 ih_hcrc; /* Image Header CRC Checksum */ +- __be32 ih_time; /* Image Creation Timestamp */ +- __be32 ih_size; /* Image Data Size */ +- __be32 ih_load; /* Data Load Address */ +- __be32 ih_ep; /* Entry Point Address */ +- __be32 ih_dcrc; /* Image Data CRC Checksum */ ++ uint32_t ih_magic; /* Image Header Magic Number */ ++ uint32_t ih_hcrc; /* Image Header CRC Checksum */ ++ uint32_t ih_time; /* Image Creation Timestamp */ ++ uint32_t ih_size; /* Image Data Size */ ++ uint32_t ih_load; /* Data Load Address */ ++ uint32_t ih_ep; /* Entry Point Address */ ++ uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ diff --git a/tools/mkimage/patches/060-remove_kernel_includes.patch b/tools/mkimage/patches/060-remove_kernel_includes.patch new file mode 100644 index 00000000000..e61d8cc4961 --- /dev/null +++ b/tools/mkimage/patches/060-remove_kernel_includes.patch @@ -0,0 +1,35 @@ +--- a/include/compiler.h ++++ b/include/compiler.h +@@ -66,6 +66,11 @@ typedef uint8_t __u8; + typedef uint16_t __u16; + typedef uint32_t __u32; + typedef unsigned int uint; ++typedef uint64_t __u64; ++#ifndef linux ++typedef int __kernel_daddr_t; ++typedef unsigned int __kernel_ino_t; ++#endif + + #define uswap_16(x) \ + ((((x) & 0xff00) >> 8) | \ +--- a/include/linux/posix_types.h ++++ b/include/linux/posix_types.h +@@ -43,6 +43,8 @@ typedef void (*__kernel_sighandler_t)(in + /* Type of a SYSV IPC key. */ + typedef int __kernel_key_t; + ++#ifdef linux + #include <asm/posix_types.h> ++#endif + + #endif /* _LINUX_POSIX_TYPES_H */ +--- a/include/linux/types.h ++++ b/include/linux/types.h +@@ -2,7 +2,6 @@ + #define _LINUX_TYPES_H + + #include <linux/posix_types.h> +-#include <asm/types.h> + #include <stdbool.h> + + #ifndef __KERNEL_STRICT_NAMES diff --git a/tools/mkimage/patches/080-remove_compiler_check.patch b/tools/mkimage/patches/080-remove_compiler_check.patch new file mode 100644 index 00000000000..5e0792f25f3 --- /dev/null +++ b/tools/mkimage/patches/080-remove_compiler_check.patch @@ -0,0 +1,16 @@ +--- a/include/linux/compiler-gcc.h ++++ b/include/linux/compiler-gcc.h +@@ -146,13 +146,6 @@ + + #if GCC_VERSION >= 40000 + +-/* GCC 4.1.[01] miscompiles __weak */ +-#ifdef __KERNEL__ +-# if GCC_VERSION >= 40100 && GCC_VERSION <= 40101 +-# error Your version of gcc miscompiles the __weak directive +-# endif +-#endif +- + #define __used __attribute__((__used__)) + #define __compiler_offsetof(a, b) \ + __builtin_offsetof(a, b) diff --git a/tools/mkimage/patches/100-freebsd-compat.patch b/tools/mkimage/patches/100-freebsd-compat.patch new file mode 100644 index 00000000000..1567285714d --- /dev/null +++ b/tools/mkimage/patches/100-freebsd-compat.patch @@ -0,0 +1,14 @@ +--- a/Makefile ++++ b/Makefile +@@ -634,7 +634,10 @@ UBOOTINCLUDE := \ + -I$(srctree)/arch/$(ARCH)/include \ + -include $(srctree)/include/linux/kconfig.h + +-NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) ++ifneq ($(shell uname),FreeBSD) ++ NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) ++endif ++ + CHECKFLAGS += $(NOSTDINC_FLAGS) + + # FIX ME diff --git a/tools/mkimage/patches/200-rsa-sign-add-support-for-libressl.patch b/tools/mkimage/patches/200-rsa-sign-add-support-for-libressl.patch new file mode 100644 index 00000000000..29058e22b71 --- /dev/null +++ b/tools/mkimage/patches/200-rsa-sign-add-support-for-libressl.patch @@ -0,0 +1,68 @@ +From 69176c8602e29f4bd30457240374800d88dc39ed Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 14 Apr 2018 22:39:34 +0200 +Subject: [PATCH] rsa-sign: add support for libressl + +--- + lib/rsa/rsa-sign.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/lib/rsa/rsa-sign.c ++++ b/lib/rsa/rsa-sign.c +@@ -21,7 +21,8 @@ + #define HAVE_ERR_REMOVE_THREAD_STATE + #endif + +-#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || \ ++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) + static void RSA_get0_key(const RSA *r, + const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) + { +@@ -300,7 +301,8 @@ static int rsa_init(void) + { + int ret; + +-#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || \ ++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) + ret = SSL_library_init(); + #else + ret = OPENSSL_init_ssl(0, NULL); +@@ -309,7 +311,7 @@ static int rsa_init(void) + fprintf(stderr, "Failure to init SSL library\n"); + return -1; + } +-#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + SSL_load_error_strings(); + + OpenSSL_add_all_algorithms(); +@@ -355,7 +357,7 @@ err_set_rsa: + err_engine_init: + ENGINE_free(e); + err_engine_by_id: +-#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + ENGINE_cleanup(); + #endif + return ret; +@@ -363,7 +365,7 @@ err_engine_by_id: + + static void rsa_remove(void) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings(); + #ifdef HAVE_ERR_REMOVE_THREAD_STATE +@@ -433,7 +435,8 @@ static int rsa_sign_with_key(RSA *rsa, s + ret = rsa_err("Could not obtain signature"); + goto err_sign; + } +- #if OPENSSL_VERSION_NUMBER < 0x10100000L ++ #if OPENSSL_VERSION_NUMBER < 0x10100000L || \ ++ defined(LIBRESSL_VERSION_NUMBER) + EVP_MD_CTX_cleanup(context); + #else + EVP_MD_CTX_reset(context); diff --git a/tools/mkimage/patches/210-link-libcrypto-static.patch b/tools/mkimage/patches/210-link-libcrypto-static.patch new file mode 100644 index 00000000000..66412ce43b5 --- /dev/null +++ b/tools/mkimage/patches/210-link-libcrypto-static.patch @@ -0,0 +1,14 @@ +OpenWrt links the libressl statically against mkimage, make sure all the +needed dependencies are added too. + +--- a/tools/Makefile ++++ b/tools/Makefile +@@ -145,7 +145,7 @@ endif + # MXSImage needs LibSSL + ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_ARMADA_38X)$(CONFIG_ARMADA_39X)$(CONFIG_FIT_SIGNATURE),) + HOSTLOADLIBES_mkimage += \ +- $(shell pkg-config --libs libssl libcrypto 2> /dev/null || echo "-lssl -lcrypto") ++ $(shell pkg-config --libs --static libssl libcrypto 2> /dev/null || echo "-lssl -lcrypto") + + # OS X deprecate openssl in favour of CommonCrypto, supress deprecation + # warnings on those systems diff --git a/tools/mklibs/Makefile b/tools/mklibs/Makefile index bd967217ead..507c2fd3949 100644 --- a/tools/mklibs/Makefile +++ b/tools/mklibs/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2009 OpenWrt.org +# Copyright (C) 2009-2013 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,13 +7,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mklibs -PKG_VERSION:=0.1.29 +PKG_VERSION:=0.1.35 PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://ftp.de.debian.org/debian/pool/main/m/mklibs/ -PKG_MD5SUM:=7f35dfdbde249a090199829c1a1222d8 +PKG_HASH:=ccb1023dc1729c5a37ca6c3eca8e4bac3491116763c8820dfce8eea4845c8567 -HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/mklibs +HOST_FIXUP:=autoreconf include $(INCLUDE_DIR)/host-build.mk @@ -21,8 +21,8 @@ HOST_CFLAGS += -I$(CURDIR)/include define Host/Install $(INSTALL_BIN) \ - $(HOST_BUILD_DIR)/src/mklibs.py \ - $(HOST_BUILD_DIR)/src/mklibs-copy.py \ + $(HOST_BUILD_DIR)/src/mklibs \ + $(HOST_BUILD_DIR)/src/mklibs-copy \ $(HOST_BUILD_DIR)/src/mklibs-readelf/mklibs-readelf \ $(STAGING_DIR_HOST)/bin/ endef diff --git a/tools/mklibs/patches/001-compile.patch b/tools/mklibs/patches/001-compile.patch new file mode 100644 index 00000000000..09b831ada2c --- /dev/null +++ b/tools/mklibs/patches/001-compile.patch @@ -0,0 +1,8 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -1,4 +1,4 @@ +-AC_INIT([mklibs],m4_esyscmd(dpkg-parsechangelog | perl -ne 'print $1 if m/^Version: (.*)$/;')) ++AC_INIT([mklibs],m4_esyscmd([head -n1 debian/changelog | awk -F'[\\\\(\\\\)]' '{ print $2 }' | xargs -I{} echo -n {}])) + AM_INIT_AUTOMAKE([foreign no-define]) + AC_CONFIG_HEADERS([config.h]) + AM_MAINTAINER_MODE diff --git a/tools/mklibs/patches/001-missing_stdio.patch b/tools/mklibs/patches/001-missing_stdio.patch deleted file mode 100644 index fe05ee29a8e..00000000000 --- a/tools/mklibs/patches/001-missing_stdio.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/src/mklibs-readelf/main.cpp -+++ b/src/mklibs-readelf/main.cpp -@@ -7,6 +7,7 @@ - - #include <elf.h> - #include <getopt.h> -+#include <stdio.h> - - #include "elf.hpp" - diff --git a/tools/mklibs/patches/002-disable_symbol_checks.patch b/tools/mklibs/patches/002-disable_symbol_checks.patch index 7ec63937c43..44be637609d 100644 --- a/tools/mklibs/patches/002-disable_symbol_checks.patch +++ b/tools/mklibs/patches/002-disable_symbol_checks.patch @@ -1,23 +1,20 @@ ---- a/src/mklibs.py -+++ b/src/mklibs.py -@@ -500,7 +500,7 @@ while 1: +--- a/src/mklibs ++++ b/src/mklibs +@@ -524,7 +524,7 @@ while 1: # No progress in last pass. Verify all remaining symbols are weak. for name in unresolved: if not needed_symbols[name].weak: -- raise "Unresolvable symbol %s" % name +- raise Exception("Unresolvable symbol %s" % name) + print "WARNING: Unresolvable symbol %s" % name break previous_pass_unresolved = unresolved -@@ -533,10 +533,7 @@ while 1: - - # which symbols are actually used from each lib +@@ -559,7 +559,7 @@ while 1: for name in needed_symbols: -- if not name in symbol_provider: -- if not needed_symbols[name].weak: -- raise "No library provides non-weak %s" % name -- else: -+ if name in symbol_provider: + if not name in symbol_provider: + if not needed_symbols[name].weak: +- raise Exception("No library provides non-weak %s" % name) ++ print "WARNING: Unresolvable symbol %s" % name + else: lib = symbol_provider[name] library_symbols_used[lib].add(library_symbols[lib][name]) - diff --git a/tools/mklibs/patches/003-no_copy.patch b/tools/mklibs/patches/003-no_copy.patch index bd6505aff99..e0ab2ac88d1 100644 --- a/tools/mklibs/patches/003-no_copy.patch +++ b/tools/mklibs/patches/003-no_copy.patch @@ -1,6 +1,6 @@ ---- a/src/mklibs.py -+++ b/src/mklibs.py -@@ -440,7 +440,7 @@ while 1: +--- a/src/mklibs ++++ b/src/mklibs +@@ -463,7 +463,7 @@ while 1: passnr = passnr + 1 # Gather all already reduced libraries and treat them as objects as well small_libs = [] @@ -9,7 +9,7 @@ obj = dest_path + "/" + lib small_libs.append(obj) inode = os.stat(obj)[ST_INO] -@@ -552,12 +552,7 @@ while 1: +@@ -579,12 +579,7 @@ while 1: if not so_file: sys.exit("File not found:" + library) pic_file = find_pic(library) @@ -23,7 +23,7 @@ # we have a pic file, recompile debug(DEBUG_SPAM, "extracting from:", pic_file, "so_file:", so_file) soname = extract_soname(so_file) -@@ -600,22 +595,14 @@ while 1: +@@ -627,22 +622,14 @@ while 1: cmd.append(library_depends_gcc_libnames(so_file)) command(target + "gcc", *cmd) diff --git a/tools/mklibs/patches/004-libpthread_link.patch b/tools/mklibs/patches/004-libpthread_link.patch index b4a6e4f5132..657e232b0cb 100644 --- a/tools/mklibs/patches/004-libpthread_link.patch +++ b/tools/mklibs/patches/004-libpthread_link.patch @@ -1,13 +1,13 @@ ---- a/src/mklibs.py -+++ b/src/mklibs.py -@@ -105,14 +105,14 @@ def library_depends(obj): +--- a/src/mklibs ++++ b/src/mklibs +@@ -106,14 +106,14 @@ def library_depends(obj): # Return a list of libraries the passed objects depend on. The # libraries are in "-lfoo" format suitable for passing to gcc. -def library_depends_gcc_libnames(obj): +def library_depends_gcc_libnames(obj, soname): if not os.access(obj, os.F_OK): - raise "Cannot find lib: " + obj + raise Exception("Cannot find lib: " + obj) libs = library_depends(obj) ret = [] for i in libs: @@ -17,7 +17,7 @@ if match.group('ld'): ret.append(find_lib(match.group(0))) elif match.group('lib'): -@@ -592,7 +592,7 @@ while 1: +@@ -619,7 +619,7 @@ while 1: cmd.extend(extra_flags) cmd.append("-lgcc") cmd.extend(["-L%s" % a for a in [dest_path] + [sysroot + b for b in lib_path if sysroot == "" or b not in ("/" + libdir + "/", "/usr/" + libdir + "/")]]) diff --git a/tools/mklibs/patches/006-duplicate_syms.patch b/tools/mklibs/patches/005-duplicate_syms.patch index 3f39ee5bb48..8428abfc9a0 100644 --- a/tools/mklibs/patches/006-duplicate_syms.patch +++ b/tools/mklibs/patches/005-duplicate_syms.patch @@ -1,6 +1,6 @@ ---- a/src/mklibs.py -+++ b/src/mklibs.py -@@ -507,7 +507,6 @@ while 1: +--- a/src/mklibs ++++ b/src/mklibs +@@ -531,7 +531,6 @@ while 1: library_symbols = {} library_symbols_used = {} @@ -8,7 +8,7 @@ # WORKAROUND: Always add libgcc on old-abi arm header = elf_header(find_lib(libraries.copy().pop())) -@@ -525,17 +524,13 @@ while 1: +@@ -549,20 +548,13 @@ while 1: library_symbols_used[library] = set() for symbol in symbols: for name in symbol.base_names(): @@ -21,7 +21,10 @@ # which symbols are actually used from each lib for name in needed_symbols: -- if name in symbol_provider: +- if not name in symbol_provider: +- if not needed_symbols[name].weak: +- print "WARNING: Unresolvable symbol %s" % name +- else: - lib = symbol_provider[name] - library_symbols_used[lib].add(library_symbols[lib][name]) + for lib in libraries: diff --git a/tools/mklibs/patches/005-readelf_fixes.patch b/tools/mklibs/patches/005-readelf_fixes.patch deleted file mode 100644 index f755942cd8a..00000000000 --- a/tools/mklibs/patches/005-readelf_fixes.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/src/mklibs-readelf/main.cpp -+++ b/src/mklibs-readelf/main.cpp -@@ -57,6 +57,10 @@ static void process_elf_header (Elf::fil - static void process_dynamics (Elf::file *file, int64_t tag) - { - const Elf::section_type<Elf::section_type_DYNAMIC> *section = file->get_section_DYNAMIC (); -+ -+ if (!section) -+ return; -+ - for (std::vector<Elf::dynamic *>::const_iterator it = section->get_dynamics ().begin (); it != section->get_dynamics ().end (); ++it) - { - Elf::dynamic *dynamic = *it; -@@ -67,6 +71,9 @@ static void process_dynamics (Elf::file - - static void process_symbols_provided (const Elf::section_type<Elf::section_type_DYNSYM> *section) - { -+ if (!section) -+ return; -+ - for (std::vector<Elf::symbol *>::const_iterator it = section->get_symbols ().begin (); it != section->get_symbols ().end (); ++it) - { - const Elf::symbol *symbol = *it; -@@ -95,6 +102,9 @@ static void process_symbols_provided (co - - static void process_symbols_undefined (const Elf::section_type<Elf::section_type_DYNSYM> *section) - { -+ if (!section) -+ return; -+ - for (std::vector<Elf::symbol *>::const_iterator it = section->get_symbols ().begin (); it != section->get_symbols ().end (); ++it) - { - const Elf::symbol *symbol = *it; diff --git a/tools/mklibs/patches/007-uclibc_init.patch b/tools/mklibs/patches/006-uclibc_init.patch index e76515085c4..2df7fe43556 100644 --- a/tools/mklibs/patches/007-uclibc_init.patch +++ b/tools/mklibs/patches/006-uclibc_init.patch @@ -1,6 +1,6 @@ ---- a/src/mklibs.py -+++ b/src/mklibs.py -@@ -571,6 +571,11 @@ while 1: +--- a/src/mklibs ++++ b/src/mklibs +@@ -595,6 +595,11 @@ while 1: extra_post_obj.append(sysroot + libc_extras_dir + "/sofini.o") symbols.add(ProvidedSymbol('__dso_handle', None, None, True)) diff --git a/tools/mklibs/patches/008-gc_sections.patch b/tools/mklibs/patches/007-gc_sections.patch index 2775493b092..068d88a532a 100644 --- a/tools/mklibs/patches/008-gc_sections.patch +++ b/tools/mklibs/patches/007-gc_sections.patch @@ -1,6 +1,6 @@ ---- a/src/mklibs.py -+++ b/src/mklibs.py -@@ -583,7 +583,7 @@ while 1: +--- a/src/mklibs ++++ b/src/mklibs +@@ -607,7 +607,7 @@ while 1: # compile in only used symbols cmd = [] cmd.extend(gcc_options) diff --git a/tools/mklibs/patches/009-uclibc_libgcc_link.patch b/tools/mklibs/patches/008-uclibc_libgcc_link.patch index 36f20671931..432a313b6c3 100644 --- a/tools/mklibs/patches/009-uclibc_libgcc_link.patch +++ b/tools/mklibs/patches/008-uclibc_libgcc_link.patch @@ -1,6 +1,6 @@ ---- a/src/mklibs.py -+++ b/src/mklibs.py -@@ -112,11 +112,8 @@ def library_depends_gcc_libnames(obj, so +--- a/src/mklibs ++++ b/src/mklibs +@@ -113,11 +113,8 @@ def library_depends_gcc_libnames(obj, so ret = [] for i in libs: match = re.match("^(((?P<ld>ld\S*)|(lib(?P<lib>\S+))))\.so.*$", i) @@ -14,7 +14,7 @@ return ' '.join(ret) class Symbol(object): -@@ -560,6 +557,7 @@ while 1: +@@ -584,6 +581,7 @@ while 1: extra_flags = [] extra_pre_obj = [] extra_post_obj = [] @@ -22,7 +22,7 @@ symbols.update(library_symbols_used[library]) -@@ -590,9 +588,10 @@ while 1: +@@ -614,9 +612,10 @@ while 1: cmd.append(pic_file) cmd.extend(extra_post_obj) cmd.extend(extra_flags) diff --git a/tools/mklibs/patches/010-uclibc_libpthread_symbols.patch b/tools/mklibs/patches/009-uclibc_libpthread_symbols.patch index 0c97216d1aa..34866f72905 100644 --- a/tools/mklibs/patches/010-uclibc_libpthread_symbols.patch +++ b/tools/mklibs/patches/009-uclibc_libpthread_symbols.patch @@ -1,6 +1,6 @@ ---- a/src/mklibs.py -+++ b/src/mklibs.py -@@ -161,9 +161,10 @@ def undefined_symbols(obj): +--- a/src/mklibs ++++ b/src/mklibs +@@ -162,9 +162,10 @@ def undefined_symbols(obj): return result class ProvidedSymbol(Symbol): @@ -12,7 +12,7 @@ def base_names(self): ret = [] -@@ -204,11 +205,15 @@ def provided_symbols(obj): +@@ -205,11 +206,15 @@ def provided_symbols(obj): if version_string.lower() not in ('base', 'none'): version = version_string @@ -29,7 +29,7 @@ return result -@@ -476,6 +481,9 @@ while 1: +@@ -500,6 +505,9 @@ while 1: debug(DEBUG_SPAM, "present_symbols adding %s" % symbol) names = symbol.base_names() for name in names: @@ -39,7 +39,7 @@ present_symbols[name] = symbol # are we finished? -@@ -567,12 +575,16 @@ while 1: +@@ -591,12 +599,16 @@ while 1: # may segfault in ptmalloc_init due to undefined weak reference extra_pre_obj.append(sysroot + libc_extras_dir + "/soinit.o") extra_post_obj.append(sysroot + libc_extras_dir + "/sofini.o") diff --git a/tools/mklibs/patches/010-remove_STT_GNU_IFUNC.patch b/tools/mklibs/patches/010-remove_STT_GNU_IFUNC.patch new file mode 100644 index 00000000000..6bae8c7ce53 --- /dev/null +++ b/tools/mklibs/patches/010-remove_STT_GNU_IFUNC.patch @@ -0,0 +1,20 @@ +--- a/src/mklibs-readelf/main.cpp ++++ b/src/mklibs-readelf/main.cpp +@@ -84,7 +84,7 @@ static void process_symbols_provided (co + continue; + if (shndx == SHN_UNDEF || shndx == SHN_ABS) + continue; +- if (type != STT_NOTYPE && type != STT_OBJECT && type != STT_FUNC && type != STT_GNU_IFUNC && type != STT_COMMON && type != STT_TLS) ++ if (type != STT_NOTYPE && type != STT_OBJECT && type != STT_FUNC && type != STT_COMMON && type != STT_TLS) + continue; + if (!name.size()) + continue; +@@ -115,7 +115,7 @@ static void process_symbols_undefined (c + continue; + if (shndx != SHN_UNDEF) + continue; +- if (type != STT_NOTYPE && type != STT_OBJECT && type != STT_FUNC && type != STT_GNU_IFUNC && type != STT_COMMON && type != STT_TLS) ++ if (type != STT_NOTYPE && type != STT_OBJECT && type != STT_FUNC && type != STT_COMMON && type != STT_TLS) + continue; + if (!name.size()) + continue; diff --git a/tools/mklibs/patches/011-remove_multiarch.patch b/tools/mklibs/patches/011-remove_multiarch.patch new file mode 100644 index 00000000000..a32d8ee17a8 --- /dev/null +++ b/tools/mklibs/patches/011-remove_multiarch.patch @@ -0,0 +1,10 @@ +--- a/src/mklibs ++++ b/src/mklibs +@@ -263,6 +263,7 @@ def extract_soname(so_file): + return "" + + def multiarch(paths): ++ return paths + devnull = open('/dev/null', 'w') + dpkg_architecture = subprocess.Popen( + ['dpkg-architecture', '-qDEB_HOST_MULTIARCH'], diff --git a/tools/mm-macros/Makefile b/tools/mm-macros/Makefile index f2a0cccbf33..2d7991455f1 100644 --- a/tools/mm-macros/Makefile +++ b/tools/mm-macros/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2010 OpenWrt.org +# Copyright (C) 2010-2016 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -8,11 +8,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mm-macros -PKG_VERSION:=0.9.2 +PKG_VERSION:=0.9.12 -PKG_SOURCE_URL:=http://ftp.gnome.org/pub/GNOME/sources/mm-common/0.9 -PKG_SOURCE:=mm-common-$(PKG_VERSION).tar.bz2 -PKG_MD5SUM:=8cdc5620bd864d1a17e353398e8ec1ab +PKG_SOURCE_URL:=@GNOME/mm-common/0.9 +PKG_SOURCE:=mm-common-$(PKG_VERSION).tar.xz +PKG_HASH:=ceffdcce1e5b52742884c233ec604bf6fded12eea9da077ce7a62c02c87e7c0b HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/mm-common-$(PKG_VERSION) diff --git a/tools/mpc/Makefile b/tools/mpc/Makefile index ab799b269e5..70dca2637d6 100644 --- a/tools/mpc/Makefile +++ b/tools/mpc/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2009 OpenWrt.org +# Copyright (C) 2009-2015 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,11 +7,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mpc -PKG_VERSION:=0.8.2 +PKG_VERSION:=1.1.0 -PKG_SOURCE_URL:=http://www.multiprecision.org/mpc/download/ +PKG_SOURCE_URL:=@GNU/mpc/ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_MD5SUM:=e98267ebd5648a39f881d66797122fb6 +PKG_HASH:=6985c538143c1208dcb1ac42cedad6ff52e267b47e5f970183a3e75125b43c2e + +HOST_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/host-build.mk @@ -23,13 +25,4 @@ HOST_CONFIGURE_ARGS += \ --with-mpfr=$(TOPDIR)/staging_dir/host \ --with-gmp=$(TOPDIR)/staging_dir/host -define Host/Configure - (cd $(HOST_BUILD_DIR)/$(3); \ - $(HOST_CONFIGURE_CMD) \ - $(HOST_CONFIGURE_VARS) \ - $(HOST_CONFIGURE_ARGS); \ - ) -endef - - $(eval $(call HostBuild)) diff --git a/tools/mpfr/Makefile b/tools/mpfr/Makefile index 72712f219dc..dfff7964ce4 100644 --- a/tools/mpfr/Makefile +++ b/tools/mpfr/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2009 OpenWrt.org +# Copyright (C) 2009-2016 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,12 +7,15 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mpfr -PKG_VERSION:=3.0.0 +PKG_VERSION:=4.0.1 +PKG_CPE_ID:=cpe:/a:mpfr:gnu_mpfr -PKG_SOURCE_URL:=http://www.mpfr.org/mpfr-$(PKG_VERSION) -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 -PKG_MD5SUM:=f45bac3584922c8004a10060ab1a8f9f +PKG_SOURCE_URL:=http://www.mpfr.org/mpfr-$(PKG_VERSION) \ + @GNU/mpfr +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_HASH:=67874a60826303ee2fb6affc6dc0ddd3e749e9bfcb4c8655e3953d0458a6e16e +HOST_BUILD_PARALLEL:=1 HOST_FIXUP:=autoreconf include $(INCLUDE_DIR)/host-build.mk @@ -22,9 +25,4 @@ HOST_CONFIGURE_ARGS += \ --disable-shared \ --with-gmp=$(STAGING_DIR_HOST) -define Host/Configure - echo "PATH=$(shell echo $$PATH)" - $(call Host/Configure/Default) -endef - $(eval $(call HostBuild)) diff --git a/tools/mpfr/patches/000-upstream_cumulative.patch b/tools/mpfr/patches/000-upstream_cumulative.patch deleted file mode 100644 index e21571b52a1..00000000000 --- a/tools/mpfr/patches/000-upstream_cumulative.patch +++ /dev/null @@ -1,1945 +0,0 @@ -diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES ---- mpfr-3.0.0-a/PATCHES 2010-06-23 11:02:49.000000000 +0000 -+++ mpfr-3.0.0-b/PATCHES 2010-06-23 11:03:36.000000000 +0000 -@@ -0,0 +1 @@ -+mpfr_out_str -diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION ---- mpfr-3.0.0-a/VERSION 2010-06-10 11:00:14.000000000 +0000 -+++ mpfr-3.0.0-b/VERSION 2010-06-23 11:03:20.000000000 +0000 -@@ -1 +1 @@ --3.0.0 -+3.0.0-p1 -diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h ---- mpfr-3.0.0-a/mpfr.h 2010-06-10 11:00:14.000000000 +0000 -+++ mpfr-3.0.0-b/mpfr.h 2010-06-23 11:03:20.000000000 +0000 -@@ -27,7 +27,7 @@ - #define MPFR_VERSION_MAJOR 3 - #define MPFR_VERSION_MINOR 0 - #define MPFR_VERSION_PATCHLEVEL 0 --#define MPFR_VERSION_STRING "3.0.0" -+#define MPFR_VERSION_STRING "3.0.0-p1" - - /* Macros dealing with MPFR VERSION */ - #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) -diff -Naurd mpfr-3.0.0-a/mpfr.texi mpfr-3.0.0-b/mpfr.texi ---- mpfr-3.0.0-a/mpfr.texi 2010-06-10 11:00:14.000000000 +0000 -+++ mpfr-3.0.0-b/mpfr.texi 2010-06-23 11:03:12.000000000 +0000 -@@ -2050,7 +2050,7 @@ - are printed. If @var{base} is greater than 10, @samp{@@} will be used - instead of @samp{e} as exponent delimiter. - --Return the number of bytes written, or if an error occurred, return 0. -+Return the number of characters written, or if an error occurred, return 0. - @end deftypefun - - @deftypefun size_t mpfr_inp_str (mpfr_t @var{rop}, FILE *@var{stream}, int @var{base}, mpfr_rnd_t @var{rnd}) -diff -Naurd mpfr-3.0.0-a/out_str.c mpfr-3.0.0-b/out_str.c ---- mpfr-3.0.0-a/out_str.c 2010-06-10 11:00:14.000000000 +0000 -+++ mpfr-3.0.0-b/out_str.c 2010-06-23 11:03:12.000000000 +0000 -@@ -22,6 +22,16 @@ - - #include "mpfr-impl.h" - -+/* Warning! S should not contain "%". */ -+#define OUT_STR_RET(S) \ -+ do \ -+ { \ -+ int r; \ -+ r = fprintf (stream, (S)); \ -+ return r < 0 ? 0 : r; \ -+ } \ -+ while (0) -+ - size_t - mpfr_out_str (FILE *stream, int base, size_t n_digits, mpfr_srcptr op, - mpfr_rnd_t rnd_mode) -@@ -29,6 +39,7 @@ - char *s, *s0; - size_t l; - mpfr_exp_t e; -+ int err; - - MPFR_ASSERTN (base >= 2 && base <= 62); - -@@ -36,37 +47,16 @@ - if (stream == NULL) - stream = stdout; - -- if (MPFR_IS_NAN(op)) -- { -- fprintf (stream, "@NaN@"); -- return 3; -- } -- -- if (MPFR_IS_INF(op)) -- { -- if (MPFR_SIGN(op) > 0) -- { -- fprintf (stream, "@Inf@"); -- return 3; -- } -- else -- { -- fprintf (stream, "-@Inf@"); -- return 4; -- } -- } -- -- if (MPFR_IS_ZERO(op)) -+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (op))) - { -- if (MPFR_SIGN(op) > 0) -- { -- fprintf(stream, "0"); -- return 1; -- } -+ if (MPFR_IS_NAN (op)) -+ OUT_STR_RET ("@NaN@"); -+ else if (MPFR_IS_INF (op)) -+ OUT_STR_RET (MPFR_IS_POS (op) ? "@Inf@" : "-@Inf@"); - else - { -- fprintf(stream, "-0"); -- return 2; -+ MPFR_ASSERTD (MPFR_IS_ZERO (op)); -+ OUT_STR_RET (MPFR_IS_POS (op) ? "0" : "-0"); - } - } - -@@ -77,21 +67,31 @@ - - l = strlen (s) + 1; /* size of allocated block returned by mpfr_get_str - - may be incorrect, as only an upper bound? */ -- if (*s == '-') -- fputc (*s++, stream); - -- /* outputs mantissa */ -- fputc (*s++, stream); e--; /* leading digit */ -- fputc ((unsigned char) MPFR_DECIMAL_POINT, stream); -- fputs (s, stream); /* rest of mantissa */ -+ /* outputs possible sign and significand */ -+ err = (*s == '-' && fputc (*s++, stream) == EOF) -+ || fputc (*s++, stream) == EOF /* leading digit */ -+ || fputc ((unsigned char) MPFR_DECIMAL_POINT, stream) == EOF -+ || fputs (s, stream) == EOF; /* trailing significand */ - (*__gmp_free_func) (s0, l); -+ if (MPFR_UNLIKELY (err)) -+ return 0; -+ -+ e--; /* due to the leading digit */ - - /* outputs exponent */ - if (e) - { -+ int r; -+ - MPFR_ASSERTN(e >= LONG_MIN); - MPFR_ASSERTN(e <= LONG_MAX); -- l += fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), (long) e); -+ -+ r = fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), (long) e); -+ if (MPFR_UNLIKELY (r < 0)) -+ return 0; -+ -+ l += r; - } - - return l; -diff -Naurd mpfr-3.0.0-a/tests/tout_str.c mpfr-3.0.0-b/tests/tout_str.c ---- mpfr-3.0.0-a/tests/tout_str.c 2010-06-10 11:00:13.000000000 +0000 -+++ mpfr-3.0.0-b/tests/tout_str.c 2010-06-23 11:03:12.000000000 +0000 -@@ -46,22 +46,54 @@ - special (void) - { - mpfr_t x; -+ unsigned int n; - - mpfr_init (x); - - mpfr_set_nan (x); -- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); -+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); -+ if (n != 5) -+ { -+ printf ("Error: mpfr_out_str (file, 10, 0, NaN, MPFR_RNDN) wrote %u " -+ "characters instead of 5.\n", n); -+ exit (1); -+ } - - mpfr_set_inf (x, 1); -- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); -+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); -+ if (n != 5) -+ { -+ printf ("Error: mpfr_out_str (file, 10, 0, +Inf, MPFR_RNDN) wrote %u " -+ "characters instead of 5.\n", n); -+ exit (1); -+ } - - mpfr_set_inf (x, -1); -- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); -+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); -+ if (n != 6) -+ { -+ printf ("Error: mpfr_out_str (file, 10, 0, -Inf, MPFR_RNDN) wrote %u " -+ "characters instead of 6.\n", n); -+ exit (1); -+ } - - mpfr_set_ui (x, 0, MPFR_RNDN); -- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); -+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); -+ if (n != 1) -+ { -+ printf ("Error: mpfr_out_str (file, 10, 0, +0, MPFR_RNDN) wrote %u " -+ "characters instead of 1.\n", n); -+ exit (1); -+ } -+ - mpfr_neg (x, x, MPFR_RNDN); -- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); -+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN); -+ if (n != 2) -+ { -+ printf ("Error: mpfr_out_str (file, 10, 0, -0, MPFR_RNDN) wrote %u " -+ "characters instead of 2.\n", n); -+ exit (1); -+ } - - mpfr_clear (x); - } -diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c ---- mpfr-3.0.0-a/version.c 2010-06-10 11:00:14.000000000 +0000 -+++ mpfr-3.0.0-b/version.c 2010-06-23 11:03:20.000000000 +0000 -@@ -25,5 +25,5 @@ - const char * - mpfr_get_version (void) - { -- return "3.0.0"; -+ return "3.0.0-p1"; - } -diff -Naurd mpfr-3.0.0-a/Makefile.in mpfr-3.0.0-b/Makefile.in ---- mpfr-3.0.0-a/Makefile.in 2010-06-10 11:00:52.000000000 +0000 -+++ mpfr-3.0.0-b/Makefile.in 2010-06-10 11:00:52.000000000 +0000 -@@ -239,6 +239,7 @@ - distuninstallcheck_listfiles = find . -type f -print - distcleancheck_listfiles = find . -type f -print - ACLOCAL = @ACLOCAL@ -+ALLOCA = @ALLOCA@ - AMTAR = @AMTAR@ - AR = @AR@ - AS = @AS@ -diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES ---- mpfr-3.0.0-a/PATCHES 2010-06-23 11:03:36.000000000 +0000 -+++ mpfr-3.0.0-b/PATCHES 2010-06-25 13:23:13.000000000 +0000 -@@ -0,0 +1 @@ -+alloca -diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION ---- mpfr-3.0.0-a/VERSION 2010-06-23 11:03:20.000000000 +0000 -+++ mpfr-3.0.0-b/VERSION 2010-06-25 13:23:13.000000000 +0000 -@@ -1 +1 @@ --3.0.0-p1 -+3.0.0-p2 -diff -Naurd mpfr-3.0.0-a/acinclude.m4 mpfr-3.0.0-b/acinclude.m4 ---- mpfr-3.0.0-a/acinclude.m4 2010-06-10 11:00:14.000000000 +0000 -+++ mpfr-3.0.0-b/acinclude.m4 2010-06-10 11:00:14.000000000 +0000 -@@ -59,6 +59,9 @@ - dnl sys/fpu.h - MIPS specific - AC_CHECK_HEADERS([sys/time.h sys/fpu.h]) - -+dnl Check how to get `alloca' -+AC_FUNC_ALLOCA -+ - dnl SIZE_MAX macro - gl_SIZE_MAX - -diff -Naurd mpfr-3.0.0-a/configure mpfr-3.0.0-b/configure ---- mpfr-3.0.0-a/configure 2010-06-10 11:00:51.000000000 +0000 -+++ mpfr-3.0.0-b/configure 2010-06-25 13:23:05.000000000 +0000 -@@ -783,6 +783,7 @@ - OBJDUMP - DLLTOOL - AS -+ALLOCA - MPFR_LIBM - ANSI2KNR - U -@@ -5622,6 +5623,197 @@ - done - - -+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works -+# for constant arguments. Useless! -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 -+$as_echo_n "checking for working alloca.h... " >&6; } -+if test "${ac_cv_working_alloca_h+set}" = set; then : -+ $as_echo_n "(cached) " >&6 -+else -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+#include <alloca.h> -+int -+main () -+{ -+char *p = (char *) alloca (2 * sizeof (int)); -+ if (p) return 0; -+ ; -+ return 0; -+} -+_ACEOF -+if ac_fn_c_try_link "$LINENO"; then : -+ ac_cv_working_alloca_h=yes -+else -+ ac_cv_working_alloca_h=no -+fi -+rm -f core conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext conftest.$ac_ext -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 -+$as_echo "$ac_cv_working_alloca_h" >&6; } -+if test $ac_cv_working_alloca_h = yes; then -+ -+$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h -+ -+fi -+ -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 -+$as_echo_n "checking for alloca... " >&6; } -+if test "${ac_cv_func_alloca_works+set}" = set; then : -+ $as_echo_n "(cached) " >&6 -+else -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+#ifdef __GNUC__ -+# define alloca __builtin_alloca -+#else -+# ifdef _MSC_VER -+# include <malloc.h> -+# define alloca _alloca -+# else -+# ifdef HAVE_ALLOCA_H -+# include <alloca.h> -+# else -+# ifdef _AIX -+ #pragma alloca -+# else -+# ifndef alloca /* predefined by HP cc +Olibcalls */ -+char *alloca (); -+# endif -+# endif -+# endif -+# endif -+#endif -+ -+int -+main () -+{ -+char *p = (char *) alloca (1); -+ if (p) return 0; -+ ; -+ return 0; -+} -+_ACEOF -+if ac_fn_c_try_link "$LINENO"; then : -+ ac_cv_func_alloca_works=yes -+else -+ ac_cv_func_alloca_works=no -+fi -+rm -f core conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext conftest.$ac_ext -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 -+$as_echo "$ac_cv_func_alloca_works" >&6; } -+ -+if test $ac_cv_func_alloca_works = yes; then -+ -+$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h -+ -+else -+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions -+# that cause trouble. Some versions do not even contain alloca or -+# contain a buggy version. If you still want to use their alloca, -+# use ar to extract alloca.o from them instead of compiling alloca.c. -+ -+ALLOCA=\${LIBOBJDIR}alloca.$ac_objext -+ -+$as_echo "#define C_ALLOCA 1" >>confdefs.h -+ -+ -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 -+$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } -+if test "${ac_cv_os_cray+set}" = set; then : -+ $as_echo_n "(cached) " >&6 -+else -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+#if defined CRAY && ! defined CRAY2 -+webecray -+#else -+wenotbecray -+#endif -+ -+_ACEOF -+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | -+ $EGREP "webecray" >/dev/null 2>&1; then : -+ ac_cv_os_cray=yes -+else -+ ac_cv_os_cray=no -+fi -+rm -f conftest* -+ -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 -+$as_echo "$ac_cv_os_cray" >&6; } -+if test $ac_cv_os_cray = yes; then -+ for ac_func in _getb67 GETB67 getb67; do -+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -+eval as_val=\$$as_ac_var -+ if test "x$as_val" = x""yes; then : -+ -+cat >>confdefs.h <<_ACEOF -+#define CRAY_STACKSEG_END $ac_func -+_ACEOF -+ -+ break -+fi -+ -+ done -+fi -+ -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 -+$as_echo_n "checking stack direction for C alloca... " >&6; } -+if test "${ac_cv_c_stack_direction+set}" = set; then : -+ $as_echo_n "(cached) " >&6 -+else -+ if test "$cross_compiling" = yes; then : -+ ac_cv_c_stack_direction=0 -+else -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+$ac_includes_default -+int -+find_stack_direction () -+{ -+ static char *addr = 0; -+ auto char dummy; -+ if (addr == 0) -+ { -+ addr = &dummy; -+ return find_stack_direction (); -+ } -+ else -+ return (&dummy > addr) ? 1 : -1; -+} -+ -+int -+main () -+{ -+ return find_stack_direction () < 0; -+} -+_ACEOF -+if ac_fn_c_try_run "$LINENO"; then : -+ ac_cv_c_stack_direction=1 -+else -+ ac_cv_c_stack_direction=-1 -+fi -+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ -+ conftest.$ac_objext conftest.beam conftest.$ac_ext -+fi -+ -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 -+$as_echo "$ac_cv_c_stack_direction" >&6; } -+cat >>confdefs.h <<_ACEOF -+#define STACK_DIRECTION $ac_cv_c_stack_direction -+_ACEOF -+ -+ -+fi -+ -+ - - for ac_header in stdint.h - do : -@@ -7564,13 +7756,13 @@ - else - lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext -- (eval echo "\"\$as_me:7567: $ac_compile\"" >&5) -+ (eval echo "\"\$as_me:7759: $ac_compile\"" >&5) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&5 -- (eval echo "\"\$as_me:7570: $NM \\\"conftest.$ac_objext\\\"\"" >&5) -+ (eval echo "\"\$as_me:7762: $NM \\\"conftest.$ac_objext\\\"\"" >&5) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&5 -- (eval echo "\"\$as_me:7573: output\"" >&5) -+ (eval echo "\"\$as_me:7765: output\"" >&5) - cat conftest.out >&5 - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" -@@ -8772,7 +8964,7 @@ - ;; - *-*-irix6*) - # Find out which ABI we are using. -- echo '#line 8775 "configure"' > conftest.$ac_ext -+ echo '#line 8967 "configure"' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? -@@ -10032,11 +10224,11 @@ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` -- (eval echo "\"\$as_me:10035: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:10227: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 -- echo "$as_me:10039: \$? = $ac_status" >&5 -+ echo "$as_me:10231: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. -@@ -10371,11 +10563,11 @@ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` -- (eval echo "\"\$as_me:10374: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:10566: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 -- echo "$as_me:10378: \$? = $ac_status" >&5 -+ echo "$as_me:10570: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. -@@ -10476,11 +10668,11 @@ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` -- (eval echo "\"\$as_me:10479: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:10671: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 -- echo "$as_me:10483: \$? = $ac_status" >&5 -+ echo "$as_me:10675: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized -@@ -10531,11 +10723,11 @@ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` -- (eval echo "\"\$as_me:10534: $lt_compile\"" >&5) -+ (eval echo "\"\$as_me:10726: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 -- echo "$as_me:10538: \$? = $ac_status" >&5 -+ echo "$as_me:10730: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized -@@ -12915,7 +13107,7 @@ - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 12918 "configure" -+#line 13110 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -13011,7 +13203,7 @@ - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 13014 "configure" -+#line 13206 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h ---- mpfr-3.0.0-a/mpfr.h 2010-06-23 11:03:20.000000000 +0000 -+++ mpfr-3.0.0-b/mpfr.h 2010-06-25 13:23:13.000000000 +0000 -@@ -27,7 +27,7 @@ - #define MPFR_VERSION_MAJOR 3 - #define MPFR_VERSION_MINOR 0 - #define MPFR_VERSION_PATCHLEVEL 0 --#define MPFR_VERSION_STRING "3.0.0-p1" -+#define MPFR_VERSION_STRING "3.0.0-p2" - - /* Macros dealing with MPFR VERSION */ - #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) -diff -Naurd mpfr-3.0.0-a/tests/Makefile.in mpfr-3.0.0-b/tests/Makefile.in ---- mpfr-3.0.0-a/tests/Makefile.in 2010-06-10 11:00:52.000000000 +0000 -+++ mpfr-3.0.0-b/tests/Makefile.in 2010-06-10 11:00:52.000000000 +0000 -@@ -960,6 +960,7 @@ - red=; grn=; lgn=; blu=; std= - DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - ACLOCAL = @ACLOCAL@ -+ALLOCA = @ALLOCA@ - AMTAR = @AMTAR@ - AR = @AR@ - AS = @AS@ -diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c ---- mpfr-3.0.0-a/version.c 2010-06-23 11:03:20.000000000 +0000 -+++ mpfr-3.0.0-b/version.c 2010-06-25 13:23:13.000000000 +0000 -@@ -25,5 +25,5 @@ - const char * - mpfr_get_version (void) - { -- return "3.0.0-p1"; -+ return "3.0.0-p2"; - } -diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES ---- mpfr-3.0.0-a/PATCHES 2010-07-10 00:11:19.000000000 +0000 -+++ mpfr-3.0.0-b/PATCHES 2010-07-10 00:12:50.000000000 +0000 -@@ -0,0 +1 @@ -+gamma_underflow -diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION ---- mpfr-3.0.0-a/VERSION 2010-06-25 13:23:13.000000000 +0000 -+++ mpfr-3.0.0-b/VERSION 2010-07-10 00:11:53.000000000 +0000 -@@ -1 +1 @@ --3.0.0-p2 -+3.0.0-p3 -diff -Naurd mpfr-3.0.0-a/gamma.c mpfr-3.0.0-b/gamma.c ---- mpfr-3.0.0-a/gamma.c 2010-06-10 11:00:14.000000000 +0000 -+++ mpfr-3.0.0-b/gamma.c 2010-07-10 00:11:46.000000000 +0000 -@@ -274,7 +274,7 @@ - /* we want an upper bound for x * [log(2-x)-1]. - since x < 0, we need a lower bound on log(2-x) */ - mpfr_ui_sub (xp, 2, x, MPFR_RNDD); -- mpfr_log (xp, xp, MPFR_RNDD); -+ mpfr_log2 (xp, xp, MPFR_RNDD); - mpfr_sub_ui (xp, xp, 1, MPFR_RNDD); - mpfr_mul (xp, xp, x, MPFR_RNDU); - -@@ -303,8 +303,8 @@ - { - mpfr_sub (tmp, tmp, tmp2, MPFR_RNDZ); /* low bnd on |sin(Pi*(2-x))| */ - mpfr_ui_div (tmp, 12, tmp, MPFR_RNDU); /* upper bound */ -- mpfr_log (tmp, tmp, MPFR_RNDU); -- mpfr_add (tmp, tmp, xp, MPFR_RNDU); -+ mpfr_log2 (tmp, tmp, MPFR_RNDU); -+ mpfr_add (xp, tmp, xp, MPFR_RNDU); - underflow = mpfr_cmp_si (xp, expo.saved_emin - 2) <= 0; - } - -diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h ---- mpfr-3.0.0-a/mpfr.h 2010-06-25 13:23:13.000000000 +0000 -+++ mpfr-3.0.0-b/mpfr.h 2010-07-10 00:11:53.000000000 +0000 -@@ -27,7 +27,7 @@ - #define MPFR_VERSION_MAJOR 3 - #define MPFR_VERSION_MINOR 0 - #define MPFR_VERSION_PATCHLEVEL 0 --#define MPFR_VERSION_STRING "3.0.0-p2" -+#define MPFR_VERSION_STRING "3.0.0-p3" - - /* Macros dealing with MPFR VERSION */ - #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) -diff -Naurd mpfr-3.0.0-a/tests/tgamma.c mpfr-3.0.0-b/tests/tgamma.c ---- mpfr-3.0.0-a/tests/tgamma.c 2010-06-10 11:00:13.000000000 +0000 -+++ mpfr-3.0.0-b/tests/tgamma.c 2010-07-10 00:11:46.000000000 +0000 -@@ -461,6 +461,20 @@ - mpfr_clear (x); - } - -+/* bug found by Stathis, only occurs on 32-bit machines */ -+static void -+test20100709 (void) -+{ -+ mpfr_t x; -+ int inex; -+ -+ mpfr_init2 (x, 100); -+ mpfr_set_str (x, "-4.6308260837372266e+07", 10, MPFR_RNDN); -+ inex = mpfr_gamma (x, x, MPFR_RNDN); -+ MPFR_ASSERTN(MPFR_IS_ZERO(x) && MPFR_IS_NEG(x) && inex > 0); -+ mpfr_clear (x); -+} -+ - int - main (int argc, char *argv[]) - { -@@ -471,6 +485,7 @@ - test_generic (2, 100, 2); - gamma_integer (); - test20071231 (); -+ test20100709 (); - - data_check ("data/gamma", mpfr_gamma, "mpfr_gamma"); - -diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c ---- mpfr-3.0.0-a/version.c 2010-06-25 13:23:13.000000000 +0000 -+++ mpfr-3.0.0-b/version.c 2010-07-10 00:11:53.000000000 +0000 -@@ -25,5 +25,5 @@ - const char * - mpfr_get_version (void) - { -- return "3.0.0-p2"; -+ return "3.0.0-p3"; - } -diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES ---- mpfr-3.0.0-a/PATCHES 2010-09-07 08:44:01.000000000 +0000 -+++ mpfr-3.0.0-b/PATCHES 2010-09-07 08:48:46.000000000 +0000 -@@ -0,0 +1 @@ -+mpfr_cmp/set_ui/si -diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION ---- mpfr-3.0.0-a/VERSION 2010-07-10 00:11:53.000000000 +0000 -+++ mpfr-3.0.0-b/VERSION 2010-09-07 08:46:06.000000000 +0000 -@@ -1 +1 @@ --3.0.0-p3 -+3.0.0-p4 -diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h ---- mpfr-3.0.0-a/mpfr.h 2010-07-10 00:11:53.000000000 +0000 -+++ mpfr-3.0.0-b/mpfr.h 2010-09-07 08:46:06.000000000 +0000 -@@ -27,7 +27,7 @@ - #define MPFR_VERSION_MAJOR 3 - #define MPFR_VERSION_MINOR 0 - #define MPFR_VERSION_PATCHLEVEL 0 --#define MPFR_VERSION_STRING "3.0.0-p3" -+#define MPFR_VERSION_STRING "3.0.0-p4" - - /* Macros dealing with MPFR VERSION */ - #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) -@@ -798,35 +798,45 @@ - anyway. Checking with other ICC versions is needed. Possibly detect - whether warnings are produced or not with a configure test. - + Remove C++ too, since it complains too much. */ -+/* Added casts to improve robustness in case of undefined behavior and -+ compiler extensions based on UB (in particular -fwrapv). MPFR doesn't -+ use such extensions, but these macros will be used by 3rd-party code, -+ where such extensions may be required. -+ Moreover casts to unsigned long have been added to avoid warnings in -+ programs that use MPFR and are compiled with -Wconversion; such casts -+ are OK since if X is a constant expression, then (unsigned long) X is -+ also a constant expression, so that the optimizations still work. */ - #if defined (__GNUC__) && !defined(__ICC) && !defined(__cplusplus) - #if (__GNUC__ >= 2) - #undef mpfr_cmp_ui --/* We use the fact that mpfr_sgn on NaN sets the erange flag and returns 0. */ --#define mpfr_cmp_ui(_f,_u) \ -- (__builtin_constant_p (_u) && (_u) == 0 ? \ -- mpfr_sgn (_f) : \ -- mpfr_cmp_ui_2exp ((_f),(_u),0)) -+/* We use the fact that mpfr_sgn on NaN sets the erange flag and returns 0. -+ But warning! mpfr_sgn is specified as a macro in the API, thus the macro -+ mustn't be used if side effects are possible, like here. */ -+#define mpfr_cmp_ui(_f,_u) \ -+ (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ? \ -+ (mpfr_sgn) (_f) : \ -+ mpfr_cmp_ui_2exp ((_f), (unsigned long) (_u), 0)) - #undef mpfr_cmp_si --#define mpfr_cmp_si(_f,_s) \ -- (__builtin_constant_p (_s) && (_s) >= 0 ? \ -- mpfr_cmp_ui ((_f), (_s)) : \ -- mpfr_cmp_si_2exp ((_f), (_s), 0)) -+#define mpfr_cmp_si(_f,_s) \ -+ (__builtin_constant_p (_s) && (long) (_s) >= 0 ? \ -+ mpfr_cmp_ui ((_f), (unsigned long) (long) (_s)) : \ -+ mpfr_cmp_si_2exp ((_f), (long) (_s), 0)) - #if __GNUC__ > 2 || __GNUC_MINOR__ >= 95 - #undef mpfr_set_ui --#define mpfr_set_ui(_f,_u,_r) \ -- (__builtin_constant_p (_u) && (_u) == 0 ? \ -- __extension__ ({ \ -- mpfr_ptr _p = (_f); \ -- _p->_mpfr_sign = 1; \ -- _p->_mpfr_exp = __MPFR_EXP_ZERO; \ -- (void) (_r); 0; }) : \ -- mpfr_set_ui_2exp ((_f), (_u), 0, (_r))) -+#define mpfr_set_ui(_f,_u,_r) \ -+ (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ? \ -+ __extension__ ({ \ -+ mpfr_ptr _p = (_f); \ -+ _p->_mpfr_sign = 1; \ -+ _p->_mpfr_exp = __MPFR_EXP_ZERO; \ -+ (void) (_r); 0; }) : \ -+ mpfr_set_ui_2exp ((_f), (unsigned long) (_u), 0, (_r))) - #endif - #undef mpfr_set_si --#define mpfr_set_si(_f,_s,_r) \ -- (__builtin_constant_p (_s) && (_s) >= 0 ? \ -- mpfr_set_ui ((_f), (_s), (_r)) : \ -- mpfr_set_si_2exp ((_f), (_s), 0, (_r))) -+#define mpfr_set_si(_f,_s,_r) \ -+ (__builtin_constant_p (_s) && (long) (_s) >= 0 ? \ -+ mpfr_set_ui ((_f), (unsigned long) (long) (_s), (_r)) : \ -+ mpfr_set_si_2exp ((_f), (long) (_s), 0, (_r))) - #endif - #endif - -diff -Naurd mpfr-3.0.0-a/tests/tcmp_ui.c mpfr-3.0.0-b/tests/tcmp_ui.c ---- mpfr-3.0.0-a/tests/tcmp_ui.c 2010-06-10 11:00:13.000000000 +0000 -+++ mpfr-3.0.0-b/tests/tcmp_ui.c 2010-09-07 08:45:12.000000000 +0000 -@@ -88,6 +88,126 @@ - mpfr_clear (x); - } - -+/* Since mpfr_cmp_ui and mpfr_cmp_si are also implemented by a macro -+ with __builtin_constant_p for GCC, check that side effects are -+ handled correctly. */ -+static void -+check_macros (void) -+{ -+ mpfr_t x; -+ int c; -+ -+ mpfr_init2 (x, 32); -+ -+ c = 0; -+ mpfr_set_ui (x, 17, MPFR_RNDN); -+ if (mpfr_cmp_ui (x, 17) != 0) -+ { -+ printf ("Error 1 on mpfr_cmp_ui(x,17) in check_macros\n"); -+ exit (1); -+ } -+ if (mpfr_cmp_ui (x, (c++, 17)) != 0) -+ { -+ printf ("Error 2 on mpfr_cmp_ui(x,17) in check_macros\n"); -+ exit (1); -+ } -+ if (c != 1) -+ { -+ printf ("Error 3 on mpfr_cmp_ui(x,17) in check_macros\n" -+ "(c = %d instead of 1)\n", c); -+ exit (1); -+ } -+ if (mpfr_cmp_si (x, 17) != 0) -+ { -+ printf ("Error 1 on mpfr_cmp_si(x,17) in check_macros\n"); -+ exit (1); -+ } -+ if (mpfr_cmp_si (x, (c++, 17)) != 0) -+ { -+ printf ("Error 2 on mpfr_cmp_si(x,17) in check_macros\n"); -+ exit (1); -+ } -+ if (c != 2) -+ { -+ printf ("Error 3 on mpfr_cmp_si(x,17) in check_macros\n" -+ "(c = %d instead of 2)\n", c); -+ exit (1); -+ } -+ -+ c = 0; -+ mpfr_set_ui (x, 0, MPFR_RNDN); -+ if (mpfr_cmp_ui (x, 0) != 0) -+ { -+ printf ("Error 1 on mpfr_cmp_ui(x,0) in check_macros\n"); -+ exit (1); -+ } -+ if (mpfr_cmp_ui (x, (c++, 0)) != 0) -+ { -+ printf ("Error 2 on mpfr_cmp_ui(x,0) in check_macros\n"); -+ exit (1); -+ } -+ if (c != 1) -+ { -+ printf ("Error 3 on mpfr_cmp_ui(x,0) in check_macros\n" -+ "(c = %d instead of 1)\n", c); -+ exit (1); -+ } -+ if (mpfr_cmp_si (x, 0) != 0) -+ { -+ printf ("Error 1 on mpfr_cmp_si(x,0) in check_macros\n"); -+ exit (1); -+ } -+ if (mpfr_cmp_si (x, (c++, 0)) != 0) -+ { -+ printf ("Error 2 on mpfr_cmp_si(x,0) in check_macros\n"); -+ exit (1); -+ } -+ if (c != 2) -+ { -+ printf ("Error 3 on mpfr_cmp_si(x,0) in check_macros\n" -+ "(c = %d instead of 2)\n", c); -+ exit (1); -+ } -+ -+ mpfr_clear (x); -+} -+ -+/* Bug in r7114 */ -+static void -+test_macros (void) -+{ -+ mpfr_t x[3]; -+ mpfr_ptr p; -+ -+ mpfr_inits (x[0], x[1], x[2], (mpfr_ptr) 0); -+ mpfr_set_ui (x[0], 0, MPFR_RNDN); -+ p = x[0]; -+ if (mpfr_cmp_ui (p++, 0) != 0) -+ { -+ printf ("Error in mpfr_cmp_ui macro: result should be 0.\n"); -+ exit (1); -+ } -+ if (p != x[1]) -+ { -+ printf ("Error in mpfr_cmp_ui macro: p - x[0] = %d (expecting 1)\n", -+ (int) (p - x[0])); -+ exit (1); -+ } -+ p = x[0]; -+ if (mpfr_cmp_si (p++, 0) != 0) -+ { -+ printf ("Error in mpfr_cmp_si macro: result should be 0.\n"); -+ exit (1); -+ } -+ if (p != x[1]) -+ { -+ printf ("Error in mpfr_cmp_si macro: p - x[0] = %d (expecting 1)\n", -+ (int) (p - x[0])); -+ exit (1); -+ } -+ mpfr_clears (x[0], x[1], x[2], (mpfr_ptr) 0); -+} -+ - int - main (void) - { -@@ -216,6 +336,8 @@ - mpfr_clear (x); - - check_nan (); -+ check_macros (); -+ test_macros (); - - tests_end_mpfr (); - return 0; -diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c ---- mpfr-3.0.0-a/version.c 2010-07-10 00:11:53.000000000 +0000 -+++ mpfr-3.0.0-b/version.c 2010-09-07 08:46:06.000000000 +0000 -@@ -25,5 +25,5 @@ - const char * - mpfr_get_version (void) - { -- return "3.0.0-p3"; -+ return "3.0.0-p4"; - } -diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES ---- mpfr-3.0.0-a/PATCHES 2010-10-21 20:28:38.000000000 +0000 -+++ mpfr-3.0.0-b/PATCHES 2010-10-21 20:28:38.000000000 +0000 -@@ -0,0 +1 @@ -+tcan_round -diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION ---- mpfr-3.0.0-a/VERSION 2010-09-07 08:46:06.000000000 +0000 -+++ mpfr-3.0.0-b/VERSION 2010-10-21 20:28:38.000000000 +0000 -@@ -1 +1 @@ --3.0.0-p4 -+3.0.0-p5 -diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h ---- mpfr-3.0.0-a/mpfr.h 2010-09-07 08:46:06.000000000 +0000 -+++ mpfr-3.0.0-b/mpfr.h 2010-10-21 20:28:38.000000000 +0000 -@@ -27,7 +27,7 @@ - #define MPFR_VERSION_MAJOR 3 - #define MPFR_VERSION_MINOR 0 - #define MPFR_VERSION_PATCHLEVEL 0 --#define MPFR_VERSION_STRING "3.0.0-p4" -+#define MPFR_VERSION_STRING "3.0.0-p5" - - /* Macros dealing with MPFR VERSION */ - #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) -diff -Naurd mpfr-3.0.0-a/tests/tcan_round.c mpfr-3.0.0-b/tests/tcan_round.c ---- mpfr-3.0.0-a/tests/tcan_round.c 2010-06-10 11:00:13.000000000 +0000 -+++ mpfr-3.0.0-b/tests/tcan_round.c 2010-10-21 20:28:38.000000000 +0000 -@@ -41,7 +41,7 @@ - /* avoid mpn_random which leaks memory */ - for (i = 0; i < n; i++) - buf[i] = randlimb (); -- p = (mpfr_prec_t) randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN; -+ p = randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN; - err = p + randlimb () % GMP_NUMB_BITS; - r1 = mpfr_round_p (buf, n, err, p); - r2 = mpfr_can_round_raw (buf, n, MPFR_SIGN_POS, err, -diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c ---- mpfr-3.0.0-a/version.c 2010-09-07 08:46:06.000000000 +0000 -+++ mpfr-3.0.0-b/version.c 2010-10-21 20:28:38.000000000 +0000 -@@ -25,5 +25,5 @@ - const char * - mpfr_get_version (void) - { -- return "3.0.0-p4"; -+ return "3.0.0-p5"; - } -diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES ---- mpfr-3.0.0-a/PATCHES 2010-10-21 20:59:32.000000000 +0000 -+++ mpfr-3.0.0-b/PATCHES 2010-10-21 20:59:32.000000000 +0000 -@@ -0,0 +1 @@ -+mpfr_sub1 -diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION ---- mpfr-3.0.0-a/VERSION 2010-10-21 20:28:38.000000000 +0000 -+++ mpfr-3.0.0-b/VERSION 2010-10-21 20:59:32.000000000 +0000 -@@ -1 +1 @@ --3.0.0-p5 -+3.0.0-p6 -diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h ---- mpfr-3.0.0-a/mpfr.h 2010-10-21 20:28:38.000000000 +0000 -+++ mpfr-3.0.0-b/mpfr.h 2010-10-21 20:59:32.000000000 +0000 -@@ -27,7 +27,7 @@ - #define MPFR_VERSION_MAJOR 3 - #define MPFR_VERSION_MINOR 0 - #define MPFR_VERSION_PATCHLEVEL 0 --#define MPFR_VERSION_STRING "3.0.0-p5" -+#define MPFR_VERSION_STRING "3.0.0-p6" - - /* Macros dealing with MPFR VERSION */ - #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) -diff -Naurd mpfr-3.0.0-a/sub1.c mpfr-3.0.0-b/sub1.c ---- mpfr-3.0.0-a/sub1.c 2010-06-10 11:00:14.000000000 +0000 -+++ mpfr-3.0.0-b/sub1.c 2010-10-21 20:59:32.000000000 +0000 -@@ -37,7 +37,9 @@ - mp_size_t cancel2, an, bn, cn, cn0; - mp_limb_t *ap, *bp, *cp; - mp_limb_t carry, bb, cc, borrow = 0; -- int inexact, shift_b, shift_c, is_exact = 1, down = 0, add_exp = 0; -+ int inexact, shift_b, shift_c, add_exp = 0; -+ int cmp_low = 0; /* used for rounding to nearest: 0 if low(b) = low(c), -+ negative if low(b) < low(c), positive if low(b)>low(c) */ - int sh, k; - MPFR_TMP_DECL(marker); - -@@ -196,7 +198,8 @@ - } - - #ifdef DEBUG -- printf ("shift_b=%d shift_c=%d diffexp=%lu\n", shift_b, shift_c, -+ printf ("rnd=%s shift_b=%d shift_c=%d diffexp=%lu\n", -+ mpfr_print_rnd_mode (rnd_mode), shift_b, shift_c, - (unsigned long) diff_exp); - #endif - -@@ -307,17 +310,18 @@ - { - if (MPFR_LIKELY(sh)) - { -- is_exact = (carry == 0); - /* can decide except when carry = 2^(sh-1) [middle] - or carry = 0 [truncate, but cannot decide inexact flag] */ -- down = (carry < (MPFR_LIMB_ONE << (sh - 1))); - if (carry > (MPFR_LIMB_ONE << (sh - 1))) - goto add_one_ulp; -- else if ((0 < carry) && down) -+ else if ((0 < carry) && (carry < (MPFR_LIMB_ONE << (sh - 1)))) - { - inexact = -1; /* result if smaller than exact value */ - goto truncate; - } -+ /* now carry = 2^(sh-1), in which case cmp_low=2, -+ or carry = 0, in which case cmp_low=0 */ -+ cmp_low = (carry == 0) ? 0 : 2; - } - } - else /* directed rounding: set rnd_mode to RNDZ iff toward zero */ -@@ -344,12 +348,32 @@ - cn -= (long int) an + cancel2; - - #ifdef DEBUG -- printf ("last %d bits from a are %lu, bn=%ld, cn=%ld\n", -+ printf ("last sh=%d bits from a are %lu, bn=%ld, cn=%ld\n", - sh, (unsigned long) carry, (long) bn, (long) cn); - #endif - -+ /* for rounding to nearest, we couldn't conclude up to here in the following -+ cases: -+ 1. sh = 0, then cmp_low=0: we can either truncate, subtract one ulp -+ or add one ulp: -1 ulp < low(b)-low(c) < 1 ulp -+ 2. sh > 0 but the low sh bits from high(b)-high(c) equal 2^(sh-1): -+ -0.5 ulp <= -1/2^sh < low(b)-low(c)-0.5 < 1/2^sh <= 0.5 ulp -+ we can't decide the rounding, in that case cmp_low=2: -+ either we truncate and flag=-1, or we add one ulp and flag=1 -+ 3. the low sh>0 bits from high(b)-high(c) equal 0: we know we have to -+ truncate but we can't decide the ternary value, here cmp_low=0: -+ -0.5 ulp <= -1/2^sh < low(b)-low(c) < 1/2^sh <= 0.5 ulp -+ we always truncate and inexact can be any of -1,0,1 -+ */ -+ -+ /* note: here cn might exceed cn0, in which case we consider a zero limb */ - for (k = 0; (bn > 0) || (cn > 0); k = 1) - { -+ /* if cmp_low < 0, we know low(b) - low(c) < 0 -+ if cmp_low > 0, we know low(b) - low(c) > 0 -+ (more precisely if cmp_low = 2, low(b) - low(c) = 0.5 ulp so far) -+ if cmp_low = 0, so far low(b) - low(c) = 0 */ -+ - /* get next limbs */ - bb = (bn > 0) ? bp[--bn] : 0; - if ((cn > 0) && (cn-- <= cn0)) -@@ -357,76 +381,115 @@ - else - cc = 0; - -- /* down is set when low(b) < low(c) */ -- if (down == 0) -- down = (bb < cc); -+ /* cmp_low compares low(b) and low(c) */ -+ if (cmp_low == 0) /* case 1 or 3 */ -+ cmp_low = (bb < cc) ? -2+k : (bb > cc) ? 1 : 0; -+ -+ /* Case 1 for k=0 splits into 7 subcases: -+ 1a: bb > cc + half -+ 1b: bb = cc + half -+ 1c: 0 < bb - cc < half -+ 1d: bb = cc -+ 1e: -half < bb - cc < 0 -+ 1f: bb - cc = -half -+ 1g: bb - cc < -half -+ -+ Case 2 splits into 3 subcases: -+ 2a: bb > cc -+ 2b: bb = cc -+ 2c: bb < cc -+ -+ Case 3 splits into 3 subcases: -+ 3a: bb > cc -+ 3b: bb = cc -+ 3c: bb < cc -+ */ - - /* the case rounding to nearest with sh=0 is special since one couldn't - subtract above 1/2 ulp in the trailing limb of the result */ -- if ((rnd_mode == MPFR_RNDN) && sh == 0 && k == 0) -+ if (rnd_mode == MPFR_RNDN && sh == 0 && k == 0) /* case 1 for k=0 */ - { - mp_limb_t half = MPFR_LIMB_HIGHBIT; - -- is_exact = (bb == cc); -- - /* add one ulp if bb > cc + half - truncate if cc - half < bb < cc + half - sub one ulp if bb < cc - half - */ - -- if (down) -+ if (cmp_low < 0) /* bb < cc: -1 ulp < low(b) - low(c) < 0, -+ cases 1e, 1f and 1g */ - { - if (cc >= half) - cc -= half; -- else -+ else /* since bb < cc < half, bb+half < 2*half */ - bb += half; -+ /* now we have bb < cc + half: -+ we have to subtract one ulp if bb < cc, -+ and truncate if bb > cc */ - } -- else /* bb >= cc */ -+ else if (cmp_low >= 0) /* bb >= cc, cases 1a to 1d */ - { - if (cc < half) - cc += half; -- else -+ else /* since bb >= cc >= half, bb - half >= 0 */ - bb -= half; -+ /* now we have bb > cc - half: we have to add one ulp if bb > cc, -+ and truncate if bb < cc */ -+ if (cmp_low > 0) -+ cmp_low = 2; - } - } - - #ifdef DEBUG -- printf (" bb=%lu cc=%lu down=%d is_exact=%d\n", -- (unsigned long) bb, (unsigned long) cc, down, is_exact); -+ printf ("k=%u bb=%lu cc=%lu cmp_low=%d\n", k, -+ (unsigned long) bb, (unsigned long) cc, cmp_low); - #endif -- if (bb < cc) -+ if (cmp_low < 0) /* low(b) - low(c) < 0: either truncate or subtract -+ one ulp */ - { - if (rnd_mode == MPFR_RNDZ) -- goto sub_one_ulp; -+ goto sub_one_ulp; /* set inexact=-1 */ - else if (rnd_mode != MPFR_RNDN) /* round away */ - { - inexact = 1; - goto truncate; - } -- else /* round to nearest: special case here since for sh=k=0 -- bb = bb0 - MPFR_LIMB_HIGHBIT */ -+ else /* round to nearest */ - { -- if (is_exact && sh == 0) -- { -- /* For k=0 we can't decide exactness since it may depend -- from low order bits. -- For k=1, the first low limbs matched: low(b)-low(c)<0. */ -- if (k) -- { -- inexact = 1; -- goto truncate; -- } -- } -- else if (down && sh == 0) -- goto sub_one_ulp; -- else -- { -- inexact = (is_exact) ? 1 : -1; -+ /* If cmp_low < 0 and bb > cc, then -0.5 ulp < low(b)-low(c) < 0, -+ whatever the value of sh. -+ If sh>0, then cmp_low < 0 implies that the initial neglected -+ sh bits were 0 (otherwise cmp_low=2 initially), thus the -+ weight of the new bits is less than 0.5 ulp too. -+ If k > 0 (and sh=0) this means that either the first neglected -+ limbs bb and cc were equal (thus cmp_low was 0 for k=0), -+ or we had bb - cc = -0.5 ulp or 0.5 ulp. -+ The last case is not possible here since we would have -+ cmp_low > 0 which is sticky. -+ In the first case (where we have cmp_low = -1), we truncate, -+ whereas in the 2nd case we have cmp_low = -2 and we subtract -+ one ulp. -+ */ -+ if (bb > cc || sh > 0 || cmp_low == -1) -+ { /* -0.5 ulp < low(b)-low(c) < 0, -+ bb > cc corresponds to cases 1e and 1f1 -+ sh > 0 corresponds to cases 3c and 3b3 -+ cmp_low = -1 corresponds to case 1d3 (also 3b3) */ -+ inexact = 1; - goto truncate; - } -+ else if (bb < cc) /* here sh = 0 and low(b)-low(c) < -0.5 ulp, -+ this corresponds to cases 1g and 1f3 */ -+ goto sub_one_ulp; -+ /* the only case where we can't conclude is sh=0 and bb=cc, -+ i.e., we have low(b) - low(c) = -0.5 ulp (up to now), thus -+ we don't know if we must truncate or subtract one ulp. -+ Note: for sh=0 we can't have low(b) - low(c) = -0.5 ulp up to -+ now, since low(b) - low(c) > 1/2^sh */ - } - } -- else if (bb > cc) -+ else if (cmp_low > 0) /* 0 < low(b) - low(c): either truncate or -+ add one ulp */ - { - if (rnd_mode == MPFR_RNDZ) - { -@@ -437,34 +500,70 @@ - goto add_one_ulp; - else /* round to nearest */ - { -- if (is_exact) -+ if (bb > cc) - { -- inexact = -1; -- goto truncate; -+ /* if sh=0, then bb>cc means that low(b)-low(c) > 0.5 ulp, -+ and similarly when cmp_low=2 */ -+ if (cmp_low == 2) /* cases 1a, 1b1, 2a and 2b1 */ -+ goto add_one_ulp; -+ /* sh > 0 and cmp_low > 0: this implies that the sh initial -+ neglected bits were 0, and the remaining low(b)-low(c)>0, -+ but its weight is less than 0.5 ulp */ -+ else /* 0 < low(b) - low(c) < 0.5 ulp, this corresponds to -+ cases 3a, 1d1 and 3b1 */ -+ { -+ inexact = -1; -+ goto truncate; -+ } - } -- else if (down) -+ else if (bb < cc) /* 0 < low(b) - low(c) < 0.5 ulp, cases 1c, -+ 1b3, 2b3 and 2c */ - { -- inexact = 1; -+ inexact = -1; - goto truncate; - } -- else -- goto add_one_ulp; -+ /* the only case where we can't conclude is bb=cc, i.e., -+ low(b) - low(c) = 0.5 ulp (up to now), thus we don't know -+ if we must truncate or add one ulp. */ - } - } -+ /* after k=0, we cannot conclude in the following cases, we split them -+ according to the values of bb and cc for k=1: -+ 1b. sh=0 and cmp_low = 1 and bb-cc = half [around 0.5 ulp] -+ 1b1. bb > cc: add one ulp, inex = 1 -+ 1b2: bb = cc: cannot conclude -+ 1b3: bb < cc: truncate, inex = -1 -+ 1d. sh=0 and cmp_low = 0 and bb-cc = 0 [around 0] -+ 1d1: bb > cc: truncate, inex = -1 -+ 1d2: bb = cc: cannot conclude -+ 1d3: bb < cc: truncate, inex = +1 -+ 1f. sh=0 and cmp_low = -1 and bb-cc = -half [around -0.5 ulp] -+ 1f1: bb > cc: truncate, inex = +1 -+ 1f2: bb = cc: cannot conclude -+ 1f3: bb < cc: sub one ulp, inex = -1 -+ 2b. sh > 0 and cmp_low = 2 and bb=cc [around 0.5 ulp] -+ 2b1. bb > cc: add one ulp, inex = 1 -+ 2b2: bb = cc: cannot conclude -+ 2b3: bb < cc: truncate, inex = -1 -+ 3b. sh > 0 and cmp_low = 0 [around 0] -+ 3b1. bb > cc: truncate, inex = -1 -+ 3b2: bb = cc: cannot conclude -+ 3b3: bb < cc: truncate, inex = +1 -+ */ - } - -- if ((rnd_mode == MPFR_RNDN) && !is_exact) -+ if ((rnd_mode == MPFR_RNDN) && cmp_low != 0) - { - /* even rounding rule */ - if ((ap[0] >> sh) & 1) - { -- if (down) -+ if (cmp_low < 0) - goto sub_one_ulp; - else - goto add_one_ulp; - } - else -- inexact = (down) ? 1 : -1; -+ inexact = (cmp_low > 0) ? -1 : 1; - } - else - inexact = 0; -diff -Naurd mpfr-3.0.0-a/tests/tfma.c mpfr-3.0.0-b/tests/tfma.c ---- mpfr-3.0.0-a/tests/tfma.c 2010-06-10 11:00:13.000000000 +0000 -+++ mpfr-3.0.0-b/tests/tfma.c 2010-10-21 20:59:32.000000000 +0000 -@@ -337,6 +337,94 @@ - mpfr_clears (x, y, z, r, (mpfr_ptr) 0); - } - -+static void -+bug20101018 (void) -+{ -+ mpfr_t x, y, z, t, u; -+ int i; -+ -+ mpfr_init2 (x, 64); -+ mpfr_init2 (y, 64); -+ mpfr_init2 (z, 64); -+ mpfr_init2 (t, 64); -+ mpfr_init2 (u, 64); -+ -+ mpfr_set_str (x, "0xf.fffffffffffffffp-14766", 16, MPFR_RNDN); -+ mpfr_set_str (y, "-0xf.fffffffffffffffp+317", 16, MPFR_RNDN); -+ mpfr_set_str (z, "0x8.3ffffffffffe3ffp-14443", 16, MPFR_RNDN); -+ mpfr_set_str (t, "0x8.7ffffffffffc7ffp-14444", 16, MPFR_RNDN); -+ i = mpfr_fma (u, x, y, z, MPFR_RNDN); -+ if (mpfr_cmp (u, t) != 0) -+ { -+ printf ("Wrong result in bug20101018 (a)\n"); -+ printf ("Expected "); -+ mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN); -+ printf ("\nGot "); -+ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN); -+ printf ("\n"); -+ exit (1); -+ } -+ if (i <= 0) -+ { -+ printf ("Wrong ternary value in bug20101018 (a)\n"); -+ printf ("Expected > 0\n"); -+ printf ("Got %d\n", i); -+ exit (1); -+ } -+ -+ mpfr_set_str (x, "-0xf.fffffffffffffffp-11420", 16, MPFR_RNDN); -+ mpfr_set_str (y, "0xf.fffffffffffffffp+9863", 16, MPFR_RNDN); -+ mpfr_set_str (z, "0x8.fffff80ffffffffp-1551", 16, MPFR_RNDN); -+ mpfr_set_str (t, "0x9.fffff01ffffffffp-1552", 16, MPFR_RNDN); -+ i = mpfr_fma (u, x, y, z, MPFR_RNDN); -+ if (mpfr_cmp (u, t) != 0) -+ { -+ printf ("Wrong result in bug20101018 (b)\n"); -+ printf ("Expected "); -+ mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN); -+ printf ("\nGot "); -+ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN); -+ printf ("\n"); -+ exit (1); -+ } -+ if (i <= 0) -+ { -+ printf ("Wrong ternary value in bug20101018 (b)\n"); -+ printf ("Expected > 0\n"); -+ printf ("Got %d\n", i); -+ exit (1); -+ } -+ -+ mpfr_set_str (x, "0xf.fffffffffffffffp-2125", 16, MPFR_RNDN); -+ mpfr_set_str (y, "-0xf.fffffffffffffffp-6000", 16, MPFR_RNDN); -+ mpfr_set_str (z, "0x8p-8119", 16, MPFR_RNDN); -+ mpfr_set_str (t, "0x8.000000000000001p-8120", 16, MPFR_RNDN); -+ i = mpfr_fma (u, x, y, z, MPFR_RNDN); -+ if (mpfr_cmp (u, t) != 0) -+ { -+ printf ("Wrong result in bug20101018 (c)\n"); -+ printf ("Expected "); -+ mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN); -+ printf ("\nGot "); -+ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN); -+ printf ("\n"); -+ exit (1); -+ } -+ if (i <= 0) -+ { -+ printf ("Wrong ternary value in bug20101018 (c)\n"); -+ printf ("Expected > 0\n"); -+ printf ("Got %d\n", i); -+ exit (1); -+ } -+ -+ mpfr_clear (x); -+ mpfr_clear (y); -+ mpfr_clear (z); -+ mpfr_clear (t); -+ mpfr_clear (u); -+} -+ - int - main (int argc, char *argv[]) - { -@@ -345,6 +433,8 @@ - - tests_start_mpfr (); - -+ bug20101018 (); -+ - mpfr_init (x); - mpfr_init (s); - mpfr_init (y); -diff -Naurd mpfr-3.0.0-a/tests/tsub.c mpfr-3.0.0-b/tests/tsub.c ---- mpfr-3.0.0-a/tests/tsub.c 2010-06-10 11:00:13.000000000 +0000 -+++ mpfr-3.0.0-b/tests/tsub.c 2010-10-21 20:59:32.000000000 +0000 -@@ -201,6 +201,8 @@ - if (mpfr_cmp (z, x)) - { - printf ("Error in mpfr_sub (2)\n"); -+ printf ("Expected "); mpfr_print_binary (x); puts (""); -+ printf ("Got "); mpfr_print_binary (z); puts (""); - exit (1); - } - mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101"); -@@ -478,6 +480,156 @@ - mpfr_clear (u); - } - -+/* Bug found by Jakub Jelinek -+ * http://bugzilla.redhat.com/643657 -+ * https://gforge.inria.fr/tracker/index.php?func=detail&aid=11301 -+ * The consequence can be either an assertion failure (i = 2 in the -+ * testcase below, in debug mode) or an incorrectly rounded value. -+ */ -+static void -+bug20101017 (void) -+{ -+ mpfr_t a, b, c; -+ int inex; -+ int i; -+ -+ mpfr_init2 (a, GMP_NUMB_BITS * 2); -+ mpfr_init2 (b, GMP_NUMB_BITS); -+ mpfr_init2 (c, GMP_NUMB_BITS); -+ -+ /* a = 2^(2N) + k.2^(2N-1) + 2^N and b = 1 -+ with N = GMP_NUMB_BITS and k = 0 or 1. -+ c = a - b should round to the same value as a. */ -+ -+ for (i = 2; i <= 3; i++) -+ { -+ mpfr_set_ui_2exp (a, i, GMP_NUMB_BITS - 1, MPFR_RNDN); -+ mpfr_add_ui (a, a, 1, MPFR_RNDN); -+ mpfr_mul_2ui (a, a, GMP_NUMB_BITS, MPFR_RNDN); -+ mpfr_set_ui (b, 1, MPFR_RNDN); -+ inex = mpfr_sub (c, a, b, MPFR_RNDN); -+ mpfr_set (b, a, MPFR_RNDN); -+ if (! mpfr_equal_p (c, b)) -+ { -+ printf ("Error in bug20101017 for i = %d.\n", i); -+ printf ("Expected "); -+ mpfr_out_str (stdout, 16, 0, b, MPFR_RNDN); -+ putchar ('\n'); -+ printf ("Got "); -+ mpfr_out_str (stdout, 16, 0, c, MPFR_RNDN); -+ putchar ('\n'); -+ exit (1); -+ } -+ if (inex >= 0) -+ { -+ printf ("Error in bug20101017 for i = %d: bad inex value.\n", i); -+ printf ("Expected negative, got %d.\n", inex); -+ exit (1); -+ } -+ } -+ -+ mpfr_set_prec (a, 64); -+ mpfr_set_prec (b, 129); -+ mpfr_set_prec (c, 2); -+ mpfr_set_str_binary (b, "0.100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001E65"); -+ mpfr_set_str_binary (c, "0.10E1"); -+ inex = mpfr_sub (a, b, c, MPFR_RNDN); -+ if (mpfr_cmp_ui_2exp (a, 1, 64) != 0 || inex >= 0) -+ { -+ printf ("Error in mpfr_sub for b-c for b=2^64+1+2^(-64), c=1\n"); -+ printf ("Expected result 2^64 with inex < 0\n"); -+ printf ("Got "); mpfr_print_binary (a); -+ printf (" with inex=%d\n", inex); -+ exit (1); -+ } -+ -+ mpfr_clears (a, b, c, (mpfr_ptr) 0); -+} -+ -+/* hard test of rounding */ -+static void -+check_rounding (void) -+{ -+ mpfr_t a, b, c, res; -+ mpfr_prec_t p; -+ long k, l; -+ int i; -+ -+#define MAXKL (2 * GMP_NUMB_BITS) -+ for (p = MPFR_PREC_MIN; p <= GMP_NUMB_BITS; p++) -+ { -+ mpfr_init2 (a, p); -+ mpfr_init2 (res, p); -+ mpfr_init2 (b, p + 1 + MAXKL); -+ mpfr_init2 (c, MPFR_PREC_MIN); -+ -+ /* b = 2^p + 1 + 2^(-k), c = 2^(-l) */ -+ for (k = 0; k <= MAXKL; k++) -+ for (l = 0; l <= MAXKL; l++) -+ { -+ mpfr_set_ui_2exp (b, 1, p, MPFR_RNDN); -+ mpfr_add_ui (b, b, 1, MPFR_RNDN); -+ mpfr_mul_2ui (b, b, k, MPFR_RNDN); -+ mpfr_add_ui (b, b, 1, MPFR_RNDN); -+ mpfr_div_2ui (b, b, k, MPFR_RNDN); -+ mpfr_set_ui_2exp (c, 1, -l, MPFR_RNDN); -+ i = mpfr_sub (a, b, c, MPFR_RNDN); -+ /* b - c = 2^p + 1 + 2^(-k) - 2^(-l), should be rounded to -+ 2^p for l <= k, and 2^p+2 for l < k */ -+ if (l <= k) -+ { -+ if (mpfr_cmp_ui_2exp (a, 1, p) != 0) -+ { -+ printf ("Wrong result in check_rounding\n"); -+ printf ("p=%lu k=%ld l=%ld\n", p, k, l); -+ printf ("b="); mpfr_print_binary (b); puts (""); -+ printf ("c="); mpfr_print_binary (c); puts (""); -+ printf ("Expected 2^%lu\n", p); -+ printf ("Got "); mpfr_print_binary (a); puts (""); -+ exit (1); -+ } -+ if (i >= 0) -+ { -+ printf ("Wrong ternary value in check_rounding\n"); -+ printf ("p=%lu k=%ld l=%ld\n", p, k, l); -+ printf ("b="); mpfr_print_binary (b); puts (""); -+ printf ("c="); mpfr_print_binary (c); puts (""); -+ printf ("a="); mpfr_print_binary (a); puts (""); -+ printf ("Expected < 0, got %d\n", i); -+ exit (1); -+ } -+ } -+ else /* l < k */ -+ { -+ mpfr_set_ui_2exp (res, 1, p, MPFR_RNDN); -+ mpfr_add_ui (res, res, 2, MPFR_RNDN); -+ if (mpfr_cmp (a, res) != 0) -+ { -+ printf ("Wrong result in check_rounding\n"); -+ printf ("b="); mpfr_print_binary (b); puts (""); -+ printf ("c="); mpfr_print_binary (c); puts (""); -+ printf ("Expected "); mpfr_print_binary (res); puts (""); -+ printf ("Got "); mpfr_print_binary (a); puts (""); -+ exit (1); -+ } -+ if (i <= 0) -+ { -+ printf ("Wrong ternary value in check_rounding\n"); -+ printf ("b="); mpfr_print_binary (b); puts (""); -+ printf ("c="); mpfr_print_binary (c); puts (""); -+ printf ("Expected > 0, got %d\n", i); -+ exit (1); -+ } -+ } -+ } -+ -+ mpfr_clear (a); -+ mpfr_clear (res); -+ mpfr_clear (b); -+ mpfr_clear (c); -+ } -+} -+ - #define TEST_FUNCTION test_sub - #define TWO_ARGS - #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS) -@@ -491,6 +643,8 @@ - - tests_start_mpfr (); - -+ bug20101017 (); -+ check_rounding (); - check_diverse (); - check_inexact (); - bug_ddefour (); -diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c ---- mpfr-3.0.0-a/version.c 2010-10-21 20:28:38.000000000 +0000 -+++ mpfr-3.0.0-b/version.c 2010-10-21 20:59:32.000000000 +0000 -@@ -25,5 +25,5 @@ - const char * - mpfr_get_version (void) - { -- return "3.0.0-p5"; -+ return "3.0.0-p6"; - } -diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES ---- mpfr-3.0.0-a/PATCHES 2010-10-21 21:18:26.000000000 +0000 -+++ mpfr-3.0.0-b/PATCHES 2010-10-21 21:18:26.000000000 +0000 -@@ -0,0 +1 @@ -+mpfr_set_ld -diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION ---- mpfr-3.0.0-a/VERSION 2010-10-21 20:59:32.000000000 +0000 -+++ mpfr-3.0.0-b/VERSION 2010-10-21 21:18:26.000000000 +0000 -@@ -1 +1 @@ --3.0.0-p6 -+3.0.0-p7 -diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h ---- mpfr-3.0.0-a/mpfr.h 2010-10-21 20:59:32.000000000 +0000 -+++ mpfr-3.0.0-b/mpfr.h 2010-10-21 21:18:26.000000000 +0000 -@@ -27,7 +27,7 @@ - #define MPFR_VERSION_MAJOR 3 - #define MPFR_VERSION_MINOR 0 - #define MPFR_VERSION_PATCHLEVEL 0 --#define MPFR_VERSION_STRING "3.0.0-p6" -+#define MPFR_VERSION_STRING "3.0.0-p7" - - /* Macros dealing with MPFR VERSION */ - #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) -diff -Naurd mpfr-3.0.0-a/set_ld.c mpfr-3.0.0-b/set_ld.c ---- mpfr-3.0.0-a/set_ld.c 2010-06-10 11:00:14.000000000 +0000 -+++ mpfr-3.0.0-b/set_ld.c 2010-10-21 21:18:26.000000000 +0000 -@@ -102,21 +102,25 @@ - { - x /= div13; /* exact */ - shift_exp += 8192; -+ mpfr_div_2si (t, t, 8192, MPFR_RNDZ); - } - if (ABS (x) >= div12) - { - x /= div12; /* exact */ - shift_exp += 4096; -+ mpfr_div_2si (t, t, 4096, MPFR_RNDZ); - } - if (ABS (x) >= div11) - { - x /= div11; /* exact */ - shift_exp += 2048; -+ mpfr_div_2si (t, t, 2048, MPFR_RNDZ); - } - if (ABS (x) >= div10) - { - x /= div10; /* exact */ - shift_exp += 1024; -+ mpfr_div_2si (t, t, 1024, MPFR_RNDZ); - } - /* warning: we may have DBL_MAX=2^1024*(1-2^(-53)) < x < 2^1024, - therefore we have one extra exponent reduction step */ -@@ -124,9 +128,10 @@ - { - x /= div9; /* exact */ - shift_exp += 512; -+ mpfr_div_2si (t, t, 512, MPFR_RNDZ); - } - } /* Check overflow of double */ -- else -+ else /* no overflow on double */ - { - long double div9, div10, div11; - -@@ -149,29 +154,34 @@ - { - x /= div13; /* exact */ - shift_exp -= 8192; -+ mpfr_mul_2si (t, t, 8192, MPFR_RNDZ); - } - if (ABS (x) <= div12) - { - x /= div12; /* exact */ - shift_exp -= 4096; -+ mpfr_mul_2si (t, t, 4096, MPFR_RNDZ); - } - if (ABS (x) <= div11) - { - x /= div11; /* exact */ - shift_exp -= 2048; -+ mpfr_mul_2si (t, t, 2048, MPFR_RNDZ); - } - if (ABS (x) <= div10) - { - x /= div10; /* exact */ - shift_exp -= 1024; -+ mpfr_mul_2si (t, t, 1024, MPFR_RNDZ); - } - if (ABS(x) <= div9) - { - x /= div9; /* exact */ - shift_exp -= 512; -+ mpfr_mul_2si (t, t, 512, MPFR_RNDZ); - } - } -- else -+ else /* no underflow */ - { - inexact = mpfr_set_d (u, (double) x, MPFR_RNDZ); - MPFR_ASSERTD (inexact == 0); -diff -Naurd mpfr-3.0.0-a/tests/tset_ld.c mpfr-3.0.0-b/tests/tset_ld.c ---- mpfr-3.0.0-a/tests/tset_ld.c 2010-06-10 11:00:13.000000000 +0000 -+++ mpfr-3.0.0-b/tests/tset_ld.c 2010-10-21 21:18:26.000000000 +0000 -@@ -147,12 +147,39 @@ - test_fixed_bugs (void) - { - mpfr_t x; -- long double d; -+ long double l, m; - - /* bug found by Steve Kargl (2009-03-14) */ - mpfr_init2 (x, 64); - mpfr_set_ui_2exp (x, 1, -16447, MPFR_RNDN); -- d = mpfr_get_ld (x, MPFR_RNDN); /* an assertion failed in init2.c:50 */ -+ mpfr_get_ld (x, MPFR_RNDN); /* an assertion failed in init2.c:50 */ -+ -+ /* bug reported by Jakub Jelinek (2010-10-17) -+ https://gforge.inria.fr/tracker/?func=detail&aid=11300 */ -+ mpfr_set_prec (x, MPFR_LDBL_MANT_DIG); -+ /* l = 0x1.23456789abcdef0123456789abcdp-914L; */ -+ l = 8.215640181713713164092636634579e-276; -+ mpfr_set_ld (x, l, MPFR_RNDN); -+ m = mpfr_get_ld (x, MPFR_RNDN); -+ if (m != l) -+ { -+ printf ("Error in get_ld o set_ld for l=%Le\n", l); -+ printf ("Got m=%Le instead of l\n", m); -+ exit (1); -+ } -+ -+ /* another similar test which failed with extended double precision and the -+ generic code for mpfr_set_ld */ -+ /* l = 0x1.23456789abcdef0123456789abcdp-968L; */ -+ l = 4.560596445887084662336528403703e-292; -+ mpfr_set_ld (x, l, MPFR_RNDN); -+ m = mpfr_get_ld (x, MPFR_RNDN); -+ if (m != l) -+ { -+ printf ("Error in get_ld o set_ld for l=%Le\n", l); -+ printf ("Got m=%Le instead of l\n", m); -+ exit (1); -+ } - - mpfr_clear (x); - } -diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c ---- mpfr-3.0.0-a/version.c 2010-10-21 20:59:32.000000000 +0000 -+++ mpfr-3.0.0-b/version.c 2010-10-21 21:18:26.000000000 +0000 -@@ -25,5 +25,5 @@ - const char * - mpfr_get_version (void) - { -- return "3.0.0-p6"; -+ return "3.0.0-p7"; - } -diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES ---- mpfr-3.0.0-a/PATCHES 2010-11-09 15:15:07.000000000 +0000 -+++ mpfr-3.0.0-b/PATCHES 2010-11-09 15:15:07.000000000 +0000 -@@ -0,0 +1 @@ -+macros -diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION ---- mpfr-3.0.0-a/VERSION 2010-10-21 21:18:26.000000000 +0000 -+++ mpfr-3.0.0-b/VERSION 2010-11-09 15:15:07.000000000 +0000 -@@ -1 +1 @@ --3.0.0-p7 -+3.0.0-p8 -diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h ---- mpfr-3.0.0-a/mpfr.h 2010-10-21 21:18:26.000000000 +0000 -+++ mpfr-3.0.0-b/mpfr.h 2010-11-09 15:15:07.000000000 +0000 -@@ -27,7 +27,7 @@ - #define MPFR_VERSION_MAJOR 3 - #define MPFR_VERSION_MINOR 0 - #define MPFR_VERSION_PATCHLEVEL 0 --#define MPFR_VERSION_STRING "3.0.0-p7" -+#define MPFR_VERSION_STRING "3.0.0-p8" - - /* Macros dealing with MPFR VERSION */ - #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) -@@ -67,6 +67,16 @@ - # define _MPFR_H_HAVE_INTMAX_T 1 - #endif - -+/* Avoid some problems with macro expansion if the user defines macros -+ with the same name as keywords. By convention, identifiers and macro -+ names starting with mpfr_ are reserved by MPFR. */ -+typedef void mpfr_void; -+typedef int mpfr_int; -+typedef unsigned int mpfr_uint; -+typedef long mpfr_long; -+typedef unsigned long mpfr_ulong; -+typedef size_t mpfr_size_t; -+ - /* Definition of rounding modes (DON'T USE MPFR_RNDNA!). - Warning! Changing the contents of this enum should be seen as an - interface change since the old and the new types are not compatible -@@ -136,7 +146,7 @@ - typedef mp_exp_t mpfr_exp_t; - - /* Definition of the standard exponent limits */ --#define MPFR_EMAX_DEFAULT ((mpfr_exp_t) (((unsigned long) 1 << 30) - 1)) -+#define MPFR_EMAX_DEFAULT ((mpfr_exp_t) (((mpfr_ulong) 1 << 30) - 1)) - #define MPFR_EMIN_DEFAULT (-(MPFR_EMAX_DEFAULT)) - - /* Definition of the main structure */ -@@ -725,13 +735,13 @@ - unexpected results with future compilers and aggressive optimisations. - Why not working only with signed types, using INT_MIN and LONG_MIN? */ - #if __GMP_MP_SIZE_T_INT --#define __MPFR_EXP_NAN ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+2)) --#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+1)) --#define __MPFR_EXP_INF ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+3)) -+#define __MPFR_EXP_NAN ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+2)) -+#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+1)) -+#define __MPFR_EXP_INF ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+3)) - #else --#define __MPFR_EXP_NAN ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+2)) --#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+1)) --#define __MPFR_EXP_INF ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+3)) -+#define __MPFR_EXP_NAN ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+2)) -+#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+1)) -+#define __MPFR_EXP_INF ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+3)) - #endif - - /* Define MPFR_USE_EXTENSION to avoid "gcc -pedantic" warnings. */ -@@ -760,9 +770,9 @@ - #define mpfr_inf_p(_x) ((_x)->_mpfr_exp == __MPFR_EXP_INF) - #define mpfr_zero_p(_x) ((_x)->_mpfr_exp == __MPFR_EXP_ZERO) - #define mpfr_regular_p(_x) ((_x)->_mpfr_exp > __MPFR_EXP_INF) --#define mpfr_sgn(_x) \ -- ((_x)->_mpfr_exp < __MPFR_EXP_INF ? \ -- (mpfr_nan_p (_x) ? mpfr_set_erangeflag () : (void) 0), 0 : \ -+#define mpfr_sgn(_x) \ -+ ((_x)->_mpfr_exp < __MPFR_EXP_INF ? \ -+ (mpfr_nan_p (_x) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : \ - MPFR_SIGN (_x)) - - /* Prevent them from using as lvalues */ -@@ -805,7 +815,19 @@ - Moreover casts to unsigned long have been added to avoid warnings in - programs that use MPFR and are compiled with -Wconversion; such casts - are OK since if X is a constant expression, then (unsigned long) X is -- also a constant expression, so that the optimizations still work. */ -+ also a constant expression, so that the optimizations still work. The -+ warnings are probably related to the following two bugs: -+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210 -+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38470 (possibly a variant) -+ and the casts could be removed once these bugs are fixed. -+ Casts shouldn't be used on the generic calls (to the ..._2exp functions), -+ where implicit conversions are performed. Indeed, having at least one -+ implicit conversion in the macro allows the compiler to emit diagnostics -+ when normally expected, for instance in the following call: -+ mpfr_set_ui (x, "foo", MPFR_RNDN); -+ If this is not possible (for future macros), one of the tricks described -+ on http://groups.google.com/group/comp.std.c/msg/e92abd24bf9eaf7b could -+ be used. */ - #if defined (__GNUC__) && !defined(__ICC) && !defined(__cplusplus) - #if (__GNUC__ >= 2) - #undef mpfr_cmp_ui -@@ -813,45 +835,45 @@ - But warning! mpfr_sgn is specified as a macro in the API, thus the macro - mustn't be used if side effects are possible, like here. */ - #define mpfr_cmp_ui(_f,_u) \ -- (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ? \ -+ (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ? \ - (mpfr_sgn) (_f) : \ -- mpfr_cmp_ui_2exp ((_f), (unsigned long) (_u), 0)) -+ mpfr_cmp_ui_2exp ((_f), (_u), 0)) - #undef mpfr_cmp_si --#define mpfr_cmp_si(_f,_s) \ -- (__builtin_constant_p (_s) && (long) (_s) >= 0 ? \ -- mpfr_cmp_ui ((_f), (unsigned long) (long) (_s)) : \ -- mpfr_cmp_si_2exp ((_f), (long) (_s), 0)) -+#define mpfr_cmp_si(_f,_s) \ -+ (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \ -+ mpfr_cmp_ui ((_f), (mpfr_ulong) (mpfr_long) (_s)) : \ -+ mpfr_cmp_si_2exp ((_f), (_s), 0)) - #if __GNUC__ > 2 || __GNUC_MINOR__ >= 95 - #undef mpfr_set_ui - #define mpfr_set_ui(_f,_u,_r) \ -- (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ? \ -+ (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ? \ - __extension__ ({ \ - mpfr_ptr _p = (_f); \ - _p->_mpfr_sign = 1; \ - _p->_mpfr_exp = __MPFR_EXP_ZERO; \ -- (void) (_r); 0; }) : \ -- mpfr_set_ui_2exp ((_f), (unsigned long) (_u), 0, (_r))) -+ (mpfr_void) (_r); 0; }) : \ -+ mpfr_set_ui_2exp ((_f), (_u), 0, (_r))) - #endif - #undef mpfr_set_si - #define mpfr_set_si(_f,_s,_r) \ -- (__builtin_constant_p (_s) && (long) (_s) >= 0 ? \ -- mpfr_set_ui ((_f), (unsigned long) (long) (_s), (_r)) : \ -- mpfr_set_si_2exp ((_f), (long) (_s), 0, (_r))) -+ (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \ -+ mpfr_set_ui ((_f), (mpfr_ulong) (mpfr_long) (_s), (_r)) : \ -+ mpfr_set_si_2exp ((_f), (_s), 0, (_r))) - #endif - #endif - - /* Macro version of mpfr_stack interface for fast access */ --#define mpfr_custom_get_size(p) ((size_t) \ -+#define mpfr_custom_get_size(p) ((mpfr_size_t) \ - (((p)+GMP_NUMB_BITS-1)/GMP_NUMB_BITS*sizeof (mp_limb_t))) - #define mpfr_custom_init(m,p) do {} while (0) --#define mpfr_custom_get_significand(x) ((void*)((x)->_mpfr_d)) -+#define mpfr_custom_get_significand(x) ((mpfr_void*)((x)->_mpfr_d)) - #define mpfr_custom_get_exp(x) ((x)->_mpfr_exp) - #define mpfr_custom_move(x,m) do { ((x)->_mpfr_d = (mp_limb_t*)(m)); } while (0) - #define mpfr_custom_init_set(x,k,e,p,m) do { \ - mpfr_ptr _x = (x); \ - mpfr_exp_t _e; \ - mpfr_kind_t _t; \ -- int _s, _k; \ -+ mpfr_int _s, _k; \ - _k = (k); \ - if (_k >= 0) { \ - _t = (mpfr_kind_t) _k; \ -@@ -868,11 +890,13 @@ - _x->_mpfr_exp = _e; \ - _x->_mpfr_d = (mp_limb_t*) (m); \ - } while (0) --#define mpfr_custom_get_kind(x) \ -- ( (x)->_mpfr_exp > __MPFR_EXP_INF ? (int)MPFR_REGULAR_KIND*MPFR_SIGN (x) \ -- : (x)->_mpfr_exp == __MPFR_EXP_INF ? (int)MPFR_INF_KIND*MPFR_SIGN (x) \ -- : (x)->_mpfr_exp == __MPFR_EXP_NAN ? (int)MPFR_NAN_KIND \ -- : (int) MPFR_ZERO_KIND * MPFR_SIGN (x) ) -+#define mpfr_custom_get_kind(x) \ -+ ( (x)->_mpfr_exp > __MPFR_EXP_INF ? \ -+ (mpfr_int) MPFR_REGULAR_KIND * MPFR_SIGN (x) \ -+ : (x)->_mpfr_exp == __MPFR_EXP_INF ? \ -+ (mpfr_int) MPFR_INF_KIND * MPFR_SIGN (x) \ -+ : (x)->_mpfr_exp == __MPFR_EXP_NAN ? (mpfr_int) MPFR_NAN_KIND \ -+ : (mpfr_int) MPFR_ZERO_KIND * MPFR_SIGN (x) ) - - - #endif /* MPFR_USE_NO_MACRO */ -diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c ---- mpfr-3.0.0-a/version.c 2010-10-21 21:18:26.000000000 +0000 -+++ mpfr-3.0.0-b/version.c 2010-11-09 15:15:07.000000000 +0000 -@@ -25,5 +25,5 @@ - const char * - mpfr_get_version (void) - { -- return "3.0.0-p7"; -+ return "3.0.0-p8"; - } diff --git a/tools/mpfr/patches/001-no_tests.patch b/tools/mpfr/patches/001-no_tests.patch deleted file mode 100644 index 08c1a4ff469..00000000000 --- a/tools/mpfr/patches/001-no_tests.patch +++ /dev/null @@ -1,26 +0,0 @@ -Index: mpfr-3.0.0/Makefile.am -=================================================================== ---- mpfr-3.0.0.orig/Makefile.am -+++ mpfr-3.0.0/Makefile.am -@@ -12,7 +12,7 @@ - AUTOMAKE_OPTIONS = gnu ansi2knr - ACLOCAL_AMFLAGS = -I m4 - --SUBDIRS = tests -+SUBDIRS = - - nobase_dist_doc_DATA = AUTHORS BUGS COPYING COPYING.LESSER FAQ.html NEWS TODO \ - examples/ReadMe examples/divworst.c examples/rndo-add.c examples/sample.c \ -Index: mpfr-3.0.0/Makefile.in -=================================================================== ---- mpfr-3.0.0.orig/Makefile.in -+++ mpfr-3.0.0/Makefile.in -@@ -357,7 +357,7 @@ top_builddir = @top_builddir@ - top_srcdir = @top_srcdir@ - AUTOMAKE_OPTIONS = gnu ansi2knr - ACLOCAL_AMFLAGS = -I m4 --SUBDIRS = tests -+SUBDIRS = - nobase_dist_doc_DATA = AUTHORS BUGS COPYING COPYING.LESSER FAQ.html NEWS TODO \ - examples/ReadMe examples/divworst.c examples/rndo-add.c examples/sample.c \ - examples/version.c diff --git a/tools/mpfr/patches/001-only_src.patch b/tools/mpfr/patches/001-only_src.patch new file mode 100644 index 00000000000..019928741af --- /dev/null +++ b/tools/mpfr/patches/001-only_src.patch @@ -0,0 +1,22 @@ +--- a/Makefile.am ++++ b/Makefile.am +@@ -18,7 +18,7 @@ AUTOMAKE_OPTIONS = gnu + # old Automake version. + ACLOCAL_AMFLAGS = -I m4 + +-SUBDIRS = doc src tests tune tools/bench ++SUBDIRS = src + + pkgconfigdir = $(libdir)/pkgconfig + pkgconfig_DATA = mpfr.pc +--- a/Makefile.in ++++ b/Makefile.in +@@ -383,7 +383,7 @@ AUTOMAKE_OPTIONS = gnu + # libtoolize and in case some developer needs to switch back to an + # old Automake version. + ACLOCAL_AMFLAGS = -I m4 +-SUBDIRS = doc src tests tune tools/bench ++SUBDIRS = src + pkgconfigdir = $(libdir)/pkgconfig + pkgconfig_DATA = mpfr.pc + nobase_dist_doc_DATA = AUTHORS BUGS COPYING COPYING.LESSER NEWS TODO \ diff --git a/tools/mpfr/patches/100-freebsd-compat.patch b/tools/mpfr/patches/100-freebsd-compat.patch new file mode 100644 index 00000000000..c357b68736f --- /dev/null +++ b/tools/mpfr/patches/100-freebsd-compat.patch @@ -0,0 +1,10 @@ +--- a/src/vasprintf.c ++++ b/src/vasprintf.c +@@ -61,6 +61,7 @@ http://www.gnu.org/licenses/ or write to + #endif /* HAVE_VA_COPY */ + + #ifdef HAVE_WCHAR_H ++#include <stddef.h> + #include <wchar.h> + #endif + diff --git a/tools/mtd-utils/Makefile b/tools/mtd-utils/Makefile index 4763aad1918..ff000b99e3a 100644 --- a/tools/mtd-utils/Makefile +++ b/tools/mtd-utils/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006-2010 OpenWrt.org +# Copyright (C) 2006-2015 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,52 +7,41 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mtd-utils -PKG_VERSION:=1.4.5 +PKG_VERSION:=2.0.2 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=git://git.infradead.org/mtd-utils.git -PKG_SOURCE_PROTO:=git -PKG_SOURCE_VERSION:=5319b84974fcb71504aed2d1b8285e9c0a4a4bb8 -PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) -PKG_CAT:=zcat +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=ftp://ftp.infradead.org/pub/mtd-utils/ +PKG_HASH:=fb3de61be8e932abb424e8ea3c30298f553d5f970ad158a737bb303bbf9660b8 -HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION) +PKG_FIXUP:=autoreconf include $(INCLUDE_DIR)/host-build.mk -HOST_CFLAGS += -I$(STAGING_DIR_HOST)/include/e2fsprogs -CFLAGS := $(HOST_CFLAGS) -I$(HOST_BUILD_DIR)/include -L$(HOST_BUILD_DIR) -L$(STAGING_DIR_HOST)/lib -DNO_NATIVE_SUPPORT ifneq ($(HOST_OS),Linux) -CFLAGS += -Dloff_t=off_t -D__BYTE_ORDER=BYTE_ORDER -include getline.h -include endian.h -I$(CURDIR)/include -include fls.h + HOST_CFLAGS += \ + -I$(CURDIR)/include \ + -Dloff_t=off_t \ + -D__BYTE_ORDER=BYTE_ORDER \ + -include endian.h \ + -DNO_NATIVE_SUPPORT \ + -include fls.h endif -MTD_MAKEOPTS = \ - CFLAGS="$(CFLAGS)" \ - WITHOUT_LZO=1 WITHOUT_XATTR=1 \ - LZMA_STATIC_LIB="$(STAGING_DIR_HOST)/lib/liblzma.a" \ - SUBDIRS="" \ - BUILDDIR="$(HOST_BUILD_DIR)" +HOST_CONFIGURE_VARS+= \ + UUID_CFLAGS="-I$(STAGING_DIR_HOST)/include/e2fsprogs/uuid" -define Host/Compile - $(MAKE) -C $(HOST_BUILD_DIR)/lib \ - $(MTD_MAKEOPTS) \ - TARGETS="libmtd.a libcrc32.a" \ - LIBS="libmtd libcrc32" - $(MAKE) -C $(HOST_BUILD_DIR) \ - $(MTD_MAKEOPTS) \ - TARGETS=mkfs.jffs2 - $(MAKE) -C $(HOST_BUILD_DIR)/ubi-utils \ - $(MTD_MAKEOPTS) \ - TARGETS=ubinize - $(MAKE) -C $(HOST_BUILD_DIR)/mkfs.ubifs \ - $(MTD_MAKEOPTS) \ - BUILDDIR="$(HOST_BUILD_DIR)/mkfs.ubifs" -endef +HOST_CONFIGURE_ARGS+= \ + --disable-tests \ + --without-xattr \ + --without-lzo + +HOST_MAKE_FLAGS += \ + PROGRAMS="mkfs.jffs2 ubinize mkfs.ubifs" define Host/Install $(CP) \ $(HOST_BUILD_DIR)/mkfs.jffs2 \ - $(HOST_BUILD_DIR)/mkfs.ubifs/mkfs.ubifs \ + $(HOST_BUILD_DIR)/mkfs.ubifs \ $(HOST_BUILD_DIR)/ubinize \ $(STAGING_DIR_HOST)/bin/ endef diff --git a/tools/mtd-utils/patches/100-optional_lzo.patch b/tools/mtd-utils/patches/100-optional_lzo.patch deleted file mode 100644 index e69de29bb2d..00000000000 --- a/tools/mtd-utils/patches/100-optional_lzo.patch +++ /dev/null diff --git a/tools/mtd-utils/patches/100-sscanf_fix.patch b/tools/mtd-utils/patches/100-sscanf_fix.patch new file mode 100644 index 00000000000..ae6f86722b9 --- /dev/null +++ b/tools/mtd-utils/patches/100-sscanf_fix.patch @@ -0,0 +1,11 @@ +--- a/jffsX-utils/mkfs.jffs2.c ++++ b/jffsX-utils/mkfs.jffs2.c +@@ -427,7 +427,7 @@ static int interpret_table_entry(struct + + if (sscanf (line, "%" SCANF_PREFIX "s %c %lo %lu %lu %lu %lu %lu %lu %lu", + SCANF_STRING(name), &type, &mode, &uid, &gid, &major, &minor, +- &start, &increment, &count) < 0) ++ &start, &increment, &count) < 10) + { + return 1; + } diff --git a/tools/mtd-utils/patches/101-ubifs-optional_lzo.patch b/tools/mtd-utils/patches/101-ubifs-optional_lzo.patch deleted file mode 100644 index e69de29bb2d..00000000000 --- a/tools/mtd-utils/patches/101-ubifs-optional_lzo.patch +++ /dev/null diff --git a/tools/mtd-utils/patches/110-portability.patch b/tools/mtd-utils/patches/110-portability.patch index 5bf1b95bc21..a2942270d72 100644 --- a/tools/mtd-utils/patches/110-portability.patch +++ b/tools/mtd-utils/patches/110-portability.patch @@ -1,5 +1,5 @@ ---- a/compr_lzo.c -+++ b/compr_lzo.c +--- a/jffsX-utils/compr_lzo.c ++++ b/jffsX-utils/compr_lzo.c @@ -26,7 +26,6 @@ #include <string.h> @@ -8,8 +8,8 @@ #include <linux/jffs2.h> #include <lzo/lzo1x.h> #include "compr.h" ---- a/compr_zlib.c -+++ b/compr_zlib.c +--- a/jffsX-utils/compr_zlib.c ++++ b/jffsX-utils/compr_zlib.c @@ -39,7 +39,6 @@ #include <zlib.h> #undef crc32 @@ -18,8 +18,8 @@ #include <linux/jffs2.h> #include "common.h" #include "compr.h" ---- a/rbtree.h -+++ b/rbtree.h +--- a/jffsX-utils/rbtree.h ++++ b/jffsX-utils/rbtree.h @@ -94,8 +94,7 @@ static inline struct page * rb_insert_pa #ifndef _LINUX_RBTREE_H #define _LINUX_RBTREE_H @@ -48,14 +48,17 @@ /* The version of UBI images supported by this implementation */ #define UBI_VERSION 1 ---- a/mkfs.ubifs/mkfs.ubifs.h -+++ b/mkfs.ubifs/mkfs.ubifs.h -@@ -34,7 +34,14 @@ +--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h ++++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h +@@ -32,7 +32,17 @@ #include <endian.h> #include <byteswap.h> #include <linux/types.h> +#ifdef __linux__ #include <linux/fs.h> ++# if defined(__x86_64__) && defined(__ILP32__) ++# define llseek lseek64 ++# endif +#else +# ifndef O_LARGEFILE +# define O_LARGEFILE 0 @@ -65,20 +68,9 @@ #include <getopt.h> #include <sys/types.h> ---- a/mkfs.ubifs/mkfs.ubifs.c -+++ b/mkfs.ubifs/mkfs.ubifs.c -@@ -821,8 +821,8 @@ int write_leb(int lnum, int len, void *b - if (ubi_leb_change_start(ubi, out_fd, lnum, c->leb_size, dtype)) - return sys_err_msg("ubi_leb_change_start failed"); - -- if (lseek64(out_fd, pos, SEEK_SET) != pos) -- return sys_err_msg("lseek64 failed seeking %lld", -+ if (llseek(out_fd, pos, SEEK_SET) != pos) -+ return sys_err_msg("llseek failed seeking %lld", - (long long)pos); - - if (write(out_fd, buf, c->leb_size) != c->leb_size) -@@ -1079,6 +1079,7 @@ static int add_inode_with_data(struct st +--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c ++++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c +@@ -1219,6 +1219,7 @@ static int add_inode(struct stat *st, in if (c->default_compr != UBIFS_COMPR_NONE) use_flags |= UBIFS_COMPR_FL; @@ -86,7 +78,7 @@ if (flags & FS_COMPR_FL) use_flags |= UBIFS_COMPR_FL; if (flags & FS_SYNC_FL) -@@ -1089,6 +1090,7 @@ static int add_inode_with_data(struct st +@@ -1229,6 +1230,7 @@ static int add_inode(struct stat *st, in use_flags |= UBIFS_APPEND_FL; if (flags & FS_DIRSYNC_FL && S_ISDIR(st->st_mode)) use_flags |= UBIFS_DIRSYNC_FL; @@ -94,7 +86,7 @@ memset(ino, 0, UBIFS_INO_NODE_SZ); -@@ -1158,7 +1160,9 @@ static int add_dir_inode(DIR *dir, ino_t +@@ -1293,7 +1295,9 @@ static int add_dir_inode(const char *pat fd = dirfd(dir); if (fd == -1) return sys_err_msg("dirfd failed"); @@ -104,20 +96,23 @@ flags = 0; } -@@ -1343,10 +1347,12 @@ static int add_file(const char *path_nam +@@ -1476,6 +1480,7 @@ static int add_file(const char *path_nam key_write(&key, &dn->key); dn->size = cpu_to_le32(bytes_read); out_len = NODE_BUFFER_SIZE - UBIFS_DATA_NODE_SZ; +#ifndef NO_NATIVE_SUPPORT if (c->default_compr == UBIFS_COMPR_NONE && (flags & FS_COMPR_FL)) + #ifdef WITHOUT_LZO +@@ -1484,6 +1489,7 @@ static int add_file(const char *path_nam use_compr = UBIFS_COMPR_LZO; + #endif else +#endif use_compr = c->default_compr; compr_type = compress_data(buf, bytes_read, &dn->data, &out_len, use_compr); -@@ -1388,7 +1394,9 @@ static int add_non_dir(const char *path_ +@@ -1527,7 +1533,9 @@ static int add_non_dir(const char *path_ if (fd == -1) return sys_err_msg("failed to open file '%s'", path_name); @@ -127,9 +122,9 @@ flags = 0; if (close(fd) == -1) return sys_err_msg("failed to close file '%s'", ---- a/mkfs.ubifs/devtable.c -+++ b/mkfs.ubifs/devtable.c -@@ -134,6 +134,7 @@ static int interpret_table_entry(const c +--- a/ubifs-utils/mkfs.ubifs/devtable.c ++++ b/ubifs-utils/mkfs.ubifs/devtable.c +@@ -135,6 +135,7 @@ static int interpret_table_entry(const c unsigned int mode = 0755, uid = 0, gid = 0, major = 0, minor = 0; unsigned int start = 0, increment = 0, count = 0; @@ -137,14 +132,44 @@ if (sscanf(line, "%1023s %c %o %u %u %u %u %u %u %u", buf, &type, &mode, &uid, &gid, &major, &minor, &start, &increment, &count) < 0) -@@ -144,8 +145,8 @@ static int interpret_table_entry(const c +@@ -145,10 +146,10 @@ static int interpret_table_entry(const c buf, type, mode, uid, gid, major, minor, start, increment, count); - len = strnlen(buf, 1024); -- if (len == 1024) + len = strlen(buf); + if (len == 0) + return err_msg("empty path"); +- if (len == 1024) + if (len == 1023) return err_msg("too long path"); - if (!strcmp(buf, "/")) + if (buf[0] != '/') +--- a/include/common.h ++++ b/include/common.h +@@ -26,7 +26,6 @@ + #include <string.h> + #include <fcntl.h> + #include <errno.h> +-#include <features.h> + #include <inttypes.h> + #include <unistd.h> + #include <sys/sysmacros.h> +--- a/include/mtd/ubifs-media.h ++++ b/include/mtd/ubifs-media.h +@@ -33,7 +33,15 @@ + #ifndef __UBIFS_MEDIA_H__ + #define __UBIFS_MEDIA_H__ + ++#ifdef __linux__ + #include <asm/byteorder.h> ++#else ++#include <stdint.h> ++typedef uint8_t __u8; ++typedef uint16_t __be16; ++typedef uint32_t __be32; ++typedef uint64_t __be64; ++#endif + + /* UBIFS node magic number (must not have the padding byte first or last) */ + #define UBIFS_NODE_MAGIC 0x06101831 diff --git a/tools/mtd-utils/patches/120-cygwin_fixes.patch b/tools/mtd-utils/patches/120-cygwin_fixes.patch deleted file mode 100644 index 3dc21614b1f..00000000000 --- a/tools/mtd-utils/patches/120-cygwin_fixes.patch +++ /dev/null @@ -1,457 +0,0 @@ ---- a/Makefile -+++ b/Makefile -@@ -12,6 +12,11 @@ else - LZOLDLIBS = -llzo2 - endif - -+ifeq ($(shell uname -o),Cygwin) -+CPPFLAGS += -I./include/cygwin -+endif -+ -+ifneq ($(shell uname -o),Cygwin) - SUBDIRS = lib ubi-utils mkfs.ubifs - TESTS = tests - -@@ -23,6 +28,10 @@ TARGETS = ftl_format flash_erase nanddum - rfddump rfdformat \ - serve_image recv_image \ - sumtool #jffs2reader -+else -+SUBDIRS = -+TARGETS = mkfs.jffs2 -+endif - SCRIPTS = flash_eraseall - - SYMLINKS = ---- /dev/null -+++ b/include/cygwin/bits-byteswap.h -@@ -0,0 +1,132 @@ -+/* Macros to swap the order of bytes in integer values. -+ Copyright (C) 1997, 1998, 2000, 2002 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#if !defined _BYTESWAP_H && !defined _NETINET_IN_H -+# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead." -+#endif -+ -+#ifndef _BITS_BYTESWAP_H -+#define _BITS_BYTESWAP_H 1 -+ -+/* Swap bytes in 16 bit value. */ -+#define __bswap_constant_16(x) \ -+ ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) -+ -+#ifdef __GNUC__ -+# if __GNUC__ >= 2 -+# define __bswap_16(x) \ -+ (__extension__ \ -+ ({ register unsigned short int __v, __x = (x); \ -+ if (__builtin_constant_p (__x)) \ -+ __v = __bswap_constant_16 (__x); \ -+ else \ -+ __asm__ ("rorw $8, %w0" \ -+ : "=r" (__v) \ -+ : "0" (__x) \ -+ : "cc"); \ -+ __v; })) -+# else -+/* This is better than nothing. */ -+# define __bswap_16(x) \ -+ (__extension__ \ -+ ({ register unsigned short int __x = (x); __bswap_constant_16 (__x); })) -+# endif -+#else -+static __inline unsigned short int -+__bswap_16 (unsigned short int __bsx) -+{ -+ return __bswap_constant_16 (__bsx); -+} -+#endif -+ -+/* Swap bytes in 32 bit value. */ -+#define __bswap_constant_32(x) \ -+ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ -+ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) -+ -+#ifdef __GNUC__ -+# if __GNUC__ >= 2 -+/* To swap the bytes in a word the i486 processors and up provide the -+ `bswap' opcode. On i386 we have to use three instructions. */ -+# if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ -+# define __bswap_32(x) \ -+ (__extension__ \ -+ ({ register unsigned int __v, __x = (x); \ -+ if (__builtin_constant_p (__x)) \ -+ __v = __bswap_constant_32 (__x); \ -+ else \ -+ __asm__ ("rorw $8, %w0;" \ -+ "rorl $16, %0;" \ -+ "rorw $8, %w0" \ -+ : "=r" (__v) \ -+ : "0" (__x) \ -+ : "cc"); \ -+ __v; })) -+# else -+# define __bswap_32(x) \ -+ (__extension__ \ -+ ({ register unsigned int __v, __x = (x); \ -+ if (__builtin_constant_p (__x)) \ -+ __v = __bswap_constant_32 (__x); \ -+ else \ -+ __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \ -+ __v; })) -+# endif -+# else -+# define __bswap_32(x) \ -+ (__extension__ \ -+ ({ register unsigned int __x = (x); __bswap_constant_32 (__x); })) -+# endif -+#else -+static __inline unsigned int -+__bswap_32 (unsigned int __bsx) -+{ -+ return __bswap_constant_32 (__bsx); -+} -+#endif -+ -+ -+#if defined __GNUC__ && __GNUC__ >= 2 -+/* Swap bytes in 64 bit value. */ -+#define __bswap_constant_64(x) \ -+ ((((x) & 0xff00000000000000ull) >> 56) \ -+ | (((x) & 0x00ff000000000000ull) >> 40) \ -+ | (((x) & 0x0000ff0000000000ull) >> 24) \ -+ | (((x) & 0x000000ff00000000ull) >> 8) \ -+ | (((x) & 0x00000000ff000000ull) << 8) \ -+ | (((x) & 0x0000000000ff0000ull) << 24) \ -+ | (((x) & 0x000000000000ff00ull) << 40) \ -+ | (((x) & 0x00000000000000ffull) << 56)) -+ -+# define __bswap_64(x) \ -+ (__extension__ \ -+ ({ union { __extension__ unsigned long long int __ll; \ -+ unsigned long int __l[2]; } __w, __r; \ -+ if (__builtin_constant_p (x)) \ -+ __r.__ll = __bswap_constant_64 (x); \ -+ else \ -+ { \ -+ __w.__ll = (x); \ -+ __r.__l[0] = __bswap_32 (__w.__l[1]); \ -+ __r.__l[1] = __bswap_32 (__w.__l[0]); \ -+ } \ -+ __r.__ll; })) -+#endif -+ -+#endif /* _BITS_BYTESWAP_H */ ---- /dev/null -+++ b/include/cygwin/byteswap.h -@@ -0,0 +1,40 @@ -+/* Copyright (C) 1997 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#ifndef _BYTESWAP_H -+#define _BYTESWAP_H 1 -+ -+/* Get the machine specific, optimized definitions. */ -+#include "bits-byteswap.h" -+ -+ -+/* The following definitions must all be macros since otherwise some -+ of the possible optimizations are not possible. */ -+ -+/* Return a value with all bytes in the 16 bit argument swapped. */ -+#define bswap_16(x) __bswap_16 (x) -+ -+/* Return a value with all bytes in the 32 bit argument swapped. */ -+#define bswap_32(x) __bswap_32 (x) -+ -+#if defined __GNUC__ && __GNUC__ >= 2 -+/* Return a value with all bytes in the 64 bit argument swapped. */ -+# define bswap_64(x) __bswap_64 (x) -+#endif -+ -+#endif /* byteswap.h */ ---- /dev/null -+++ b/include/cygwin/endian.h -@@ -0,0 +1,26 @@ -+#ifndef _CYGENDIAN_H_ -+#define _CYGENDIAN_H_ -+ -+#ifdef __CYGWIN__ -+ -+#include <sys/param.h> -+ -+#ifndef __BIG_ENDIAN -+#define __BIG_ENDIAN 4321 -+#endif -+ -+#ifndef __LITTLE_ENDIAN -+#define __LITTLE_ENDIAN 1234 -+#endif -+ -+#ifndef __BYTE_ORDER -+#define __BYTE_ORDER __LITTLE_ENDIAN -+#endif -+ -+#ifndef BYTE_ORDER -+#define BYTE_ORDER __LITTLE_ENDIAN -+#endif -+ -+#endif /* __CYGWIN__ */ -+ -+#endif /* _CYGENDIAN_H_ */ ---- /dev/null -+++ b/include/cygwin/ioctl.h -@@ -0,0 +1,38 @@ -+#ifndef _CYGIOCTL_H_ -+#define _CYGIOCTL_H_ -+ -+#ifdef __CYGWIN__ -+ -+#define _IOC_NRBITS 8 -+#define _IOC_TYPEBITS 8 -+#define _IOC_SIZEBITS 14 -+#define _IOC_DIRBITS 2 -+ -+#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) -+#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) -+#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) -+#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) -+ -+#define _IOC_NRSHIFT 0 -+#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) -+#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) -+#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) -+ -+#define _IOC_NONE 0U -+#define _IOC_WRITE 1U -+#define _IOC_READ 2U -+ -+#define _IOC(dir,type,nr,size) \ -+ (((dir) << _IOC_DIRSHIFT) | \ -+ ((type) << _IOC_TYPESHIFT) | \ -+ ((nr) << _IOC_NRSHIFT) | \ -+ ((size) << _IOC_SIZESHIFT)) -+ -+#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) -+#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) -+#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) -+#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) -+ -+#endif /* __CYGWIN__ */ -+ -+#endif /* _CYGIOCTL_H_ */ ---- /dev/null -+++ b/include/cygwin/pread.c -@@ -0,0 +1,41 @@ -+#ifdef __CYGWIN__ -+ -+#include <errno.h> -+ -+ssize_t -+pread(int fd, void *p, size_t n, off_t off) -+{ -+ off_t ooff; -+ int oerrno; -+ -+ if ((ooff = lseek(fd, off, SEEK_SET)) == -1) -+ return -1; -+ -+ n = read(fd, p, n); -+ -+ oerrno = errno; -+ lseek(fd, ooff, SEEK_SET); -+ errno = oerrno; -+ -+ return n; -+} -+ -+ssize_t -+pwrite(int fd, const void *p, size_t n, off_t off) -+{ -+ off_t ooff; -+ int oerrno; -+ -+ if ((ooff = lseek(fd, off, SEEK_SET)) == -1) -+ return -1; -+ -+ n = write(fd, p, n); -+ -+ oerrno = errno; -+ lseek(fd, ooff, SEEK_SET); -+ errno = oerrno; -+ -+ return n; -+} -+ -+#endif /* __CYGWIN__ */ ---- /dev/null -+++ b/lnconf.sh -@@ -0,0 +1,53 @@ -+#!/bin/sh -+# -+# Generic configure replacement. -+# -+# $Id: lnconf.sh,v 1.1 2004/04/05 21:55:59 igor Exp $ -+# -+# Copies all files from the script directory to the current one. -+# Intended to replace 'configure' for packages that don't have one, to -+# allow building outside of the source tree. -+# -+# Note: this does not do any fancy things with detecting shells and -+# supporting other platforms. But it should work on Cygwin. -+ -+# find out where the script is located -+tdir=`echo "$0" | sed 's%[\\/][^\\/][^\\/]*$%%'` -+test "x$tdir" = "x$0" && tdir=. -+ -+a_srcdir=`cd $tdir; pwd` -+a_destdir=`pwd` -+ -+# sanity checks: -+# are we in the script directory? -+test "x$a_srcdir" = "x$a_destdir" && exit 0 -+# is there any chance that this is the script directory? -+test "x`cd "$a_srcdir" && /bin/ls -id`" = "x`/bin/ls -id`" && exit 0 -+ -+# try to find lndir and use it if it's available -+LNDIR="`which lndir 2>/dev/null`" -+if [ "x$LNDIR" = "x" ]; then -+ lndir() { -+ test "x$1" = "x" && return 1 -+ # be careful of the current directory -+ DINODE=`find . -maxdepth 0 -ls | sed 's/ .*$//'` -+ case "`pwd`" in -+ "`cd "$1" && pwd`"/*) CUR="-type d -inum $DINODE -prune -o";; -+ esac -+ # duplicate the directory structure -+ (cd "$1" && find . $CUR -type d -mindepth 1 -print) | xargs -tr mkdir -p -+ # copy all symbolic links -+ (cd "$1" && find . $CUR -type l -mindepth 1 -print) | xargs -ri sh -c "ln -s \"\`readlink "$1/{}"\`\" \"{}\"" -+ # or simply -+ #(cd "$1" && find . $CUR -type l -mindepth 1 -print) | xargs -ri ln -s "$1"/{} {} -+ # link all files -+ (cd "$1" && find . $CUR -type f -mindepth 1 -print) | xargs -ri ln -s "$1"/{} {} -+ } -+else -+ lndir() { -+ "$LNDIR" "$@" -+ } -+fi -+ -+lndir "$tdir" -+ ---- a/mkfs.jffs2.c -+++ b/mkfs.jffs2.c -@@ -77,6 +77,14 @@ - #include "rbtree.h" - #include "common.h" - -+#ifdef __CYGWIN__ -+#include <cygwin/ioctl.h> -+#include <cygwin/endian.h> -+#include <cygwin/pread.c> -+# define IFTODT(mode) (((mode) & 0170000) >> 12) -+# define DTTOIF(dirtype) ((dirtype) << 12) -+#endif /* __CYGWIN__ */ -+ - /* Do not use the weird XPG version of basename */ - #undef basename - -@@ -376,7 +384,7 @@ static struct filesystem_entry *recursiv - the following macros use it if available or use a hacky workaround... - */ - --#ifdef __GNUC__ -+#if defined __GNUC__ && !defined __CYGWIN__ - #define SCANF_PREFIX "a" - #define SCANF_STRING(s) (&s) - #define GETCWD_SIZE 0 -@@ -459,6 +467,14 @@ static int interpret_table_entry(struct - } - entry = find_filesystem_entry(root, name, mode); - if (entry && !(count > 0 && (type == 'c' || type == 'b'))) { -+ /* Check the type */ -+ if ((mode & S_IFMT) != (entry->sb.st_mode & S_IFMT)) { -+ error_msg ("skipping device_table entry '%s': type mismatch!", name); -+ free(name); -+ free(hostpath); -+ return 1; -+ } -+ - /* Ok, we just need to fixup the existing entry - * and we will be all done... */ - entry->sb.st_uid = uid; -@@ -468,11 +484,21 @@ static int interpret_table_entry(struct - entry->sb.st_rdev = makedev(major, minor); - } - } else { -+ if (type == 'f' || type == 'l') { -+ error_msg ("skipping device_table entry '%s': file does not exist!", name); -+ free(name); -+ free(hostpath); -+ return 1; -+ } - /* If parent is NULL (happens with device table entries), - * try and find our parent now) */ - tmp = strdup(name); - dir = dirname(tmp); -- parent = find_filesystem_entry(root, dir, S_IFDIR); -+ if (!strcmp(dir, "/")) { -+ parent = root; -+ } else { -+ parent = find_filesystem_entry(root, dir, S_IFDIR); -+ } - free(tmp); - if (parent == NULL) { - errmsg ("skipping device_table entry '%s': no parent directory!", name); -@@ -486,6 +512,7 @@ static int interpret_table_entry(struct - add_host_filesystem_entry(name, hostpath, uid, gid, mode, 0, parent); - break; - case 'f': -+ case 'l': - add_host_filesystem_entry(name, hostpath, uid, gid, mode, 0, parent); - break; - case 'p': ---- a/ubi-utils/src/libubi.c -+++ b/ubi-utils/src/libubi.c -@@ -32,6 +32,9 @@ - #include <sys/ioctl.h> - #include <sys/stat.h> - #include <sys/types.h> -+#ifdef __CYGWIN__ -+#include <cygwin/ioctl.h> -+#endif - #include <libubi.h> - #include "libubi_int.h" - #include "common.h" diff --git a/tools/mtd-utils/patches/130-lzma_jffs2.patch b/tools/mtd-utils/patches/130-lzma_jffs2.patch index be1c361fe1d..d9cbfeebec1 100644 --- a/tools/mtd-utils/patches/130-lzma_jffs2.patch +++ b/tools/mtd-utils/patches/130-lzma_jffs2.patch @@ -1,33 +1,35 @@ ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ +--- a/jffsX-utils/Makemodule.am ++++ b/jffsX-utils/Makemodule.am +@@ -4,11 +4,19 @@ mkfs_jffs2_SOURCES = \ + jffsX-utils/compr_zlib.c \ + jffsX-utils/compr.h \ + jffsX-utils/rbtree.c \ +- jffsX-utils/compr_lzo.c \ ++ jffsX-utils/compr_lzma.c \ ++ jffsX-utils/lzma/LzFind.c \ ++ jffsX-utils/lzma/LzmaEnc.c \ ++ jffsX-utils/lzma/LzmaDec.c \ + jffsX-utils/compr.c \ + jffsX-utils/compr_rtime.c ++ ++if !WITHOUT_LZO ++mkfs_jffs2_SOURCES += jffsX-utils/compr_lzo.c ++endif ++ + mkfs_jffs2_LDADD = libmtd.a $(ZLIB_LIBS) $(LZO_LIBS) +-mkfs_jffs2_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CFLAGS) $(LZO_CFLAGS) ++mkfs_jffs2_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CFLAGS) $(LZO_CFLAGS) -I./include/linux/lzma - # -*- sh -*- - --CPPFLAGS += -I./include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) -+CPPFLAGS += -I./include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) -I./include/linux/lzma - - ifeq ($(WITHOUT_XATTR), 1) - CPPFLAGS += -DWITHOUT_XATTR -@@ -59,7 +59,9 @@ $(SYMLINKS): - ln -sf ../fs/jffs2/$@ $@ - - $(BUILDDIR)/mkfs.jffs2: $(addprefix $(BUILDDIR)/,\ -- compr_rtime.o mkfs.jffs2.o compr_zlib.o compr_lzo.o \ -+ compr_rtime.o mkfs.jffs2.o compr_zlib.o \ -+ $(if $(WITHOUT_LZO),,compr_lzo.o) \ -+ compr_lzma.o lzma/LzFind.o lzma/LzmaEnc.o lzma/LzmaDec.o \ - compr.o rbtree.o) - LDFLAGS_mkfs.jffs2 = $(ZLIBLDFLAGS) $(LZOLDFLAGS) - LDLIBS_mkfs.jffs2 = -lz $(LZOLDLIBS) ---- a/compr.c -+++ b/compr.c + jffs2reader_SOURCES = jffsX-utils/jffs2reader.c + jffs2reader_LDADD = libmtd.a $(ZLIB_LIBS) $(LZO_LIBS) +--- a/jffsX-utils/compr.c ++++ b/jffsX-utils/compr.c @@ -520,6 +520,9 @@ int jffs2_compressors_init(void) #ifdef CONFIG_JFFS2_LZO jffs2_lzo_init(); #endif +#ifdef CONFIG_JFFS2_LZMA -+ jffs2_lzma_init(); ++ jffs2_lzma_init(); +#endif return 0; } @@ -37,12 +39,12 @@ jffs2_lzo_exit(); #endif +#ifdef CONFIG_JFFS2_LZMA -+ jffs2_lzma_exit(); ++ jffs2_lzma_exit(); +#endif return 0; } ---- a/compr.h -+++ b/compr.h +--- a/jffsX-utils/compr.h ++++ b/jffsX-utils/compr.h @@ -18,13 +18,14 @@ #define CONFIG_JFFS2_ZLIB @@ -73,7 +75,7 @@ #endif /* __JFFS2_COMPR_H__ */ --- /dev/null -+++ b/compr_lzma.c ++++ b/jffsX-utils/compr_lzma.c @@ -0,0 +1,128 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. @@ -120,11 +122,11 @@ + return -1; + } + -+ return 0; ++ return 0; +} + +STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out, -+ uint32_t *sourcelen, uint32_t *dstlen, void *model) ++ uint32_t *sourcelen, uint32_t *dstlen) +{ + SizeT compress_size = (SizeT)(*dstlen); + int ret; @@ -149,7 +151,7 @@ +} + +STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, -+ uint32_t srclen, uint32_t destlen, void *model) ++ uint32_t srclen, uint32_t destlen) +{ + int ret; + SizeT dl = (SizeT)destlen; @@ -176,26 +178,26 @@ + +int INIT jffs2_lzma_init(void) +{ -+ int ret; ++ int ret; + CLzmaEncProps props; + LzmaEncProps_Init(&props); + -+ props.dictSize = LZMA_BEST_DICT(0x2000); -+ props.level = LZMA_BEST_LEVEL; -+ props.lc = LZMA_BEST_LC; -+ props.lp = LZMA_BEST_LP; -+ props.pb = LZMA_BEST_PB; -+ props.fb = LZMA_BEST_FB; ++ props.dictSize = LZMA_BEST_DICT(0x2000); ++ props.level = LZMA_BEST_LEVEL; ++ props.lc = LZMA_BEST_LC; ++ props.lp = LZMA_BEST_LP; ++ props.pb = LZMA_BEST_PB; ++ props.fb = LZMA_BEST_FB; + + ret = lzma_alloc_workspace(&props); -+ if (ret < 0) -+ return ret; ++ if (ret < 0) ++ return ret; + + ret = jffs2_register_compressor(&jffs2_lzma_comp); + if (ret) + lzma_free_workspace(); + -+ return ret; ++ return ret; +} + +void jffs2_lzma_exit(void) @@ -246,7 +248,7 @@ + #define LZMA_FREE free + #define PRINT_ERROR(msg) fprintf(stderr, msg) + #define INIT -+ #define STATIC ++ #define STATIC static +#endif + +#include "lzma/LzmaDec.h" @@ -262,16 +264,16 @@ + +static void *p_lzma_malloc(void *p, size_t size) +{ -+ if (size == 0) -+ return NULL; ++ if (size == 0) ++ return NULL; + -+ return LZMA_MALLOC(size); ++ return LZMA_MALLOC(size); +} + +static void p_lzma_free(void *p, void *address) +{ -+ if (address != NULL) -+ LZMA_FREE(address); ++ if (address != NULL) ++ LZMA_FREE(address); +} + +static ISzAlloc lzma_alloc = {p_lzma_malloc, p_lzma_free}; @@ -901,7 +903,7 @@ + +#endif --- /dev/null -+++ b/lzma/LzFind.c ++++ b/jffsX-utils/lzma/LzFind.c @@ -0,0 +1,753 @@ +/* LzFind.c -- Match finder for LZ algorithms +2008-04-04 @@ -950,9 +952,9 @@ +} + +Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } ++static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } + -+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } ++static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } + +void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) +{ @@ -1657,7 +1659,7 @@ + } +} --- /dev/null -+++ b/lzma/LzmaDec.c ++++ b/jffsX-utils/lzma/LzmaDec.c @@ -0,0 +1,1014 @@ +/* LzmaDec.c -- LZMA Decoder +2008-04-29 @@ -2358,7 +2360,7 @@ + p->needFlush = 0; +} + -+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) ++static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) +{ + p->needFlush = 1; + p->remainLen = 0; @@ -2674,7 +2676,7 @@ + return res; +} --- /dev/null -+++ b/lzma/LzmaEnc.c ++++ b/jffsX-utils/lzma/LzmaEnc.c @@ -0,0 +1,2335 @@ +/* LzmaEnc.c -- LZMA Encoder +2008-04-28 @@ -2778,7 +2780,7 @@ +#define kNumLogBits (9 + (int)sizeof(size_t) / 2) +#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) + -+void LzmaEnc_FastPosInit(Byte *g_FastPos) ++static void LzmaEnc_FastPosInit(Byte *g_FastPos) +{ + int c = 2, slotFast; + g_FastPos[0] = 0; @@ -3032,7 +3034,7 @@ + CSaveState saveState; +} CLzmaEnc; + -+void LzmaEnc_SaveState(CLzmaEncHandle pp) ++static void LzmaEnc_SaveState(CLzmaEncHandle pp) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CSaveState *dest = &p->saveState; @@ -3058,7 +3060,7 @@ + memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); +} + -+void LzmaEnc_RestoreState(CLzmaEncHandle pp) ++static void LzmaEnc_RestoreState(CLzmaEncHandle pp) +{ + CLzmaEnc *dest = (CLzmaEnc *)pp; + const CSaveState *p = &dest->saveState; @@ -3301,7 +3303,7 @@ + while (symbol < 0x10000); +} + -+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) ++static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) +{ + UInt32 i; + for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) @@ -4427,7 +4429,7 @@ + p->matchPriceCount = 0; +} + -+void LzmaEnc_Construct(CLzmaEnc *p) ++static void LzmaEnc_Construct(CLzmaEnc *p) +{ + RangeEnc_Construct(&p->rc); + MatchFinder_Construct(&p->matchFinderBase); @@ -4460,7 +4462,7 @@ + return p; +} + -+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) ++static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->litProbs); + alloc->Free(alloc, p->saveState.litProbs); @@ -4468,7 +4470,7 @@ + p->saveState.litProbs = 0; +} + -+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) ++static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + #ifdef COMPRESS_MF_MT + MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); @@ -4699,7 +4701,7 @@ + return SZ_OK; +} + -+void LzmaEnc_Init(CLzmaEnc *p) ++static void LzmaEnc_Init(CLzmaEnc *p) +{ + UInt32 i; + p->state = 0; @@ -4758,7 +4760,7 @@ + p->lpMask = (1 << p->lp) - 1; +} + -+void LzmaEnc_InitPrices(CLzmaEnc *p) ++static void LzmaEnc_InitPrices(CLzmaEnc *p) +{ + if (!p->fastMode) + { @@ -4799,7 +4801,7 @@ + return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); +} + -+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ++static SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, + ISeqInStream *inStream, UInt32 keepWindowSize, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ @@ -4815,7 +4817,7 @@ + p->seqBufInStream.rem = srcLen; +} + -+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, ++static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; @@ -4824,7 +4826,7 @@ + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + -+void LzmaEnc_Finish(CLzmaEncHandle pp) ++static void LzmaEnc_Finish(CLzmaEncHandle pp) +{ + #ifdef COMPRESS_MF_MT + CLzmaEnc *p = (CLzmaEnc *)pp; @@ -4856,19 +4858,19 @@ +} + + -+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) ++static UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); +} + -+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) ++static const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; +} + -+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, ++static SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; @@ -5011,9 +5013,9 @@ + LzmaEnc_Destroy(p, alloc, allocBig); + return res; +} ---- a/mkfs.jffs2.c -+++ b/mkfs.jffs2.c -@@ -1685,11 +1685,11 @@ int main(int argc, char **argv) +--- a/jffsX-utils/mkfs.jffs2.c ++++ b/jffsX-utils/mkfs.jffs2.c +@@ -1666,11 +1666,11 @@ int main(int argc, char **argv) } erase_block_size *= units; diff --git a/tools/mtd-utils/patches/131-fix_lib_compile.patch b/tools/mtd-utils/patches/131-fix_lib_compile.patch deleted file mode 100644 index 8c977c1774d..00000000000 --- a/tools/mtd-utils/patches/131-fix_lib_compile.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -7,7 +7,7 @@ SUBDIRS = - # CFLAGS += -Werror - CPPFLAGS += -I../include - LIBS = libmtd --TARGETS = libmtd.a -+override TARGETS = libmtd.a - - include ../common.mk - diff --git a/tools/mtd-utils/patches/133-error-fix.patch b/tools/mtd-utils/patches/133-error-fix.patch deleted file mode 100644 index 4854138d023..00000000000 --- a/tools/mtd-utils/patches/133-error-fix.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/mkfs.jffs2.c -+++ b/mkfs.jffs2.c -@@ -469,7 +469,7 @@ static int interpret_table_entry(struct - if (entry && !(count > 0 && (type == 'c' || type == 'b'))) { - /* Check the type */ - if ((mode & S_IFMT) != (entry->sb.st_mode & S_IFMT)) { -- error_msg ("skipping device_table entry '%s': type mismatch!", name); -+ sys_errmsg ("skipping device_table entry '%s': type mismatch!", name); - free(name); - free(hostpath); - return 1; -@@ -485,7 +485,7 @@ static int interpret_table_entry(struct - } - } else { - if (type == 'f' || type == 'l') { -- error_msg ("skipping device_table entry '%s': file does not exist!", name); -+ sys_errmsg ("skipping device_table entry '%s': file does not exist!", name); - free(name); - free(hostpath); - return 1; diff --git a/tools/mtd-utils/patches/134-freebsd_loff_t.patch b/tools/mtd-utils/patches/134-freebsd_loff_t.patch index 68a835292ca..2d141bd7a3a 100644 --- a/tools/mtd-utils/patches/134-freebsd_loff_t.patch +++ b/tools/mtd-utils/patches/134-freebsd_loff_t.patch @@ -1,13 +1,14 @@ --- a/include/mtd/mtd-abi.h +++ b/include/mtd/mtd-abi.h -@@ -114,8 +114,8 @@ struct otp_info { - #define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) - #define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) +@@ -171,9 +171,9 @@ struct otp_info { + /* Get info about OOB modes (e.g., RAW, PLACE, AUTO) - legacy interface */ #define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo) + /* Check if an eraseblock is bad */ -#define MEMGETBADBLOCK _IOW('M', 11, __kernel_loff_t) --#define MEMSETBADBLOCK _IOW('M', 12, __kernel_loff_t) +#define MEMGETBADBLOCK _IOW('M', 11, loff_t) + /* Mark an eraseblock as bad */ +-#define MEMSETBADBLOCK _IOW('M', 12, __kernel_loff_t) +#define MEMSETBADBLOCK _IOW('M', 12, loff_t) + /* Set OTP (One-Time Programmable) mode (factory vs. user) */ #define OTPSELECT _IOR('M', 13, int) - #define OTPGETREGIONCOUNT _IOW('M', 14, int) - #define OTPGETREGIONINFO _IOW('M', 15, struct otp_info) + /* Get number of OTP (One-Time Programmable) regions */ diff --git a/tools/mtd-utils/patches/135-mkubifs_optional_lzo.patch b/tools/mtd-utils/patches/135-mkubifs_optional_lzo.patch deleted file mode 100644 index 82b6c2fe94e..00000000000 --- a/tools/mtd-utils/patches/135-mkubifs_optional_lzo.patch +++ /dev/null @@ -1,119 +0,0 @@ ---- a/mkfs.ubifs/compr.c -+++ b/mkfs.ubifs/compr.c -@@ -24,7 +24,6 @@ - #include <stdio.h> - #include <stdint.h> - #include <string.h> --#include <lzo/lzo1x.h> - #include <linux/types.h> - - #define crc32 __zlib_crc32 -@@ -35,7 +34,6 @@ - #include "ubifs-media.h" - #include "mkfs.ubifs.h" - --static void *lzo_mem; - static unsigned long long errcnt = 0; - static struct ubifs_info *c = &info_; - -@@ -86,6 +84,25 @@ static int zlib_deflate(void *in_buf, si - return 0; - } - -+#ifndef WITHOUT_LZO -+#include <lzo/lzo1x.h> -+ -+static void *lzo_mem; -+ -+static int lzo_init(void) -+{ -+ lzo_mem = malloc(LZO1X_999_MEM_COMPRESS); -+ if (!lzo_mem) -+ return -1; -+ -+ return 0; -+} -+ -+static void lzo_fini(void) -+{ -+ free(lzo_mem); -+} -+ - static int lzo_compress(void *in_buf, size_t in_len, void *out_buf, - size_t *out_len) - { -@@ -103,6 +120,12 @@ static int lzo_compress(void *in_buf, si - - return 0; - } -+#else -+static inline int lzo_compress(void *in_buf, size_t in_len, void *out_buf, -+ size_t *out_len) { return -1; } -+static inline int lzo_init(void) { return 0; } -+static inline void lzo_fini(void) { } -+#endif - - static int no_compress(void *in_buf, size_t in_len, void *out_buf, - size_t *out_len) -@@ -123,7 +146,6 @@ static int favor_lzo_compress(void *in_b - lzo_len = zlib_len = *out_len; - lzo_ret = lzo_compress(in_buf, in_len, out_buf, &lzo_len); - zlib_ret = zlib_deflate(in_buf, in_len, zlib_buf, &zlib_len); -- - if (lzo_ret && zlib_ret) - /* Both compressors failed */ - return -1; -@@ -198,23 +220,28 @@ int compress_data(void *in_buf, size_t i - - int init_compression(void) - { -- lzo_mem = malloc(LZO1X_999_MEM_COMPRESS); -- if (!lzo_mem) -- return -1; -+ int ret; -+ -+ ret = lzo_init(); -+ if (ret) -+ goto err; - - zlib_buf = malloc(UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR); -- if (!zlib_buf) { -- free(lzo_mem); -- return -1; -- } -+ if (!zlib_buf) -+ goto err_lzo; - - return 0; -+ -+err_lzo: -+ lzo_fini(); -+err: -+ return ret; - } - - void destroy_compression(void) - { - free(zlib_buf); -- free(lzo_mem); -+ lzo_fini(); - if (errcnt) - fprintf(stderr, "%llu compression errors occurred\n", errcnt); - } ---- a/mkfs.ubifs/Makefile -+++ b/mkfs.ubifs/Makefile -@@ -6,7 +6,13 @@ ALL_SOURCES=*.[ch] hashtable/*.[ch] - - TARGETS = mkfs.ubifs - --LDLIBS_mkfs.ubifs = -lz -llzo2 -lm -luuid -L$(BUILDDIR)/../ubi-utils/ -lubi -+ifeq ($(WITHOUT_LZO), 1) -+ CPPFLAGS += -DWITHOUT_LZO -+else -+ LZOLDLIBS = -llzo2 -+endif -+ -+LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) -lm -luuid -L$(BUILDDIR)/../ubi-utils/ -lubi - LDLIBS_mkfs.ubifs += -L$(BUILDDIR)/../lib -lmtd - LDLIBS_mkfs.ubifs += $(ZLIBLDFLAGS) $(LZOLDFLAGS) - diff --git a/tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch b/tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch deleted file mode 100644 index 1e44ba4c274..00000000000 --- a/tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch +++ /dev/null @@ -1,404 +0,0 @@ ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - - # -*- sh -*- - --CPPFLAGS += -I./include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) -I./include/linux/lzma -+CPPFLAGS += -I./include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) $(XZCPPFLAGS) -I./include/linux/lzma - - ifeq ($(WITHOUT_XATTR), 1) - CPPFLAGS += -DWITHOUT_XATTR ---- a/mkfs.ubifs/compr.c -+++ b/mkfs.ubifs/compr.c -@@ -127,6 +127,114 @@ static inline int lzo_init(void) { retur - static inline void lzo_fini(void) { } - #endif - -+#ifndef WITHOUT_XZ -+ -+#include <lzma.h> -+ -+struct xz_ctx { -+ lzma_filter filters[3]; -+ lzma_options_lzma opts; -+}; -+ -+static struct xz_ctx *xz_ctx; -+ -+#define LZMA_COMPRESSION_LEVEL 9 -+ -+static struct xz_ctx *xz_ctx_init(void) -+{ -+ struct xz_ctx *ctx; -+ lzma_options_lzma *opts_lzma; -+ uint32_t preset; -+ int ret; -+ -+ ctx = malloc(sizeof(struct xz_ctx)); -+ if (ctx == NULL) -+ goto err; -+ -+ memset(ctx, 0, sizeof(struct xz_ctx)); -+ -+ opts_lzma = &ctx->opts; -+ -+ preset = LZMA_COMPRESSION_LEVEL | LZMA_PRESET_EXTREME; -+ ret = lzma_lzma_preset(opts_lzma, preset); -+ if (ret) -+ goto err_free_ctx; -+ -+ /* TODO: allow to specify LZMA options via command line */ -+#if 0 -+ opts_lzma->lc = 3; -+ opts_lzma->lp = 0; -+ opts_lzma->pb = 2; -+ opts_lzma->nice_len = 64; -+#else -+ opts_lzma->lc = 0; -+ opts_lzma->lp = 2; -+ opts_lzma->pb = 2; -+ opts_lzma->nice_len = 64; -+#endif -+ -+ ctx->filters[0].id = LZMA_FILTER_LZMA2; -+ ctx->filters[0].options = opts_lzma; -+ ctx->filters[1].id = LZMA_VLI_UNKNOWN; -+ -+ return ctx; -+ -+err_free_ctx: -+ free(ctx); -+err: -+ return NULL; -+} -+ -+static void xz_ctx_free(struct xz_ctx *ctx) -+{ -+ free(ctx); -+} -+ -+static int xz_init(void) -+{ -+ xz_ctx = xz_ctx_init(); -+ if (xz_ctx == NULL) -+ return -1; -+ -+ return 0; -+} -+ -+static void xz_fini(void) -+{ -+ xz_ctx_free(xz_ctx); -+} -+ -+static int xz_compress(void *in_buf, size_t in_len, void *out_buf, -+ size_t *out_len) -+{ -+ size_t ret_len; -+ lzma_ret ret_xz; -+ int ret; -+ -+ ret = -1; -+ -+ ret_len = 0; -+ ret_xz = lzma_stream_buffer_encode(xz_ctx->filters, LZMA_CHECK_CRC32, -+ NULL, in_buf, in_len, out_buf, -+ &ret_len, *out_len); -+ if (ret_xz != LZMA_OK) { -+ fprintf(stderr, "XZ error: %d\n", (int) ret_xz); -+ goto out; -+ } -+ -+ *out_len = ret_len; -+ -+ ret = 0; -+out: -+ return ret; -+} -+#else -+static inline int xz_init(void) { return 0; } -+static inline void xz_fini(void) { } -+static inline int xz_compress(void *in_buf, size_t in_len, void *out_buf, -+ size_t *out_len) { return -1; } -+#endif -+ - static int no_compress(void *in_buf, size_t in_len, void *out_buf, - size_t *out_len) - { -@@ -199,6 +307,9 @@ int compress_data(void *in_buf, size_t i - case MKFS_UBIFS_COMPR_LZO: - ret = lzo_compress(in_buf, in_len, out_buf, out_len); - break; -+ case MKFS_UBIFS_COMPR_XZ: -+ ret = xz_compress(in_buf, in_len, out_buf, out_len); -+ break; - case MKFS_UBIFS_COMPR_ZLIB: - ret = zlib_deflate(in_buf, in_len, out_buf, out_len); - break; -@@ -226,12 +337,18 @@ int init_compression(void) - if (ret) - goto err; - -+ ret = xz_init(); -+ if (ret) -+ goto err_lzo; -+ - zlib_buf = malloc(UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR); - if (!zlib_buf) -- goto err_lzo; -+ goto err_xz; - - return 0; - -+err_xz: -+ xz_fini(); - err_lzo: - lzo_fini(); - err: -@@ -241,6 +358,7 @@ err: - void destroy_compression(void) - { - free(zlib_buf); -+ xz_fini(); - lzo_fini(); - if (errcnt) - fprintf(stderr, "%llu compression errors occurred\n", errcnt); ---- a/mkfs.ubifs/compr.h -+++ b/mkfs.ubifs/compr.h -@@ -36,6 +36,7 @@ enum compression_type - MKFS_UBIFS_COMPR_NONE, - MKFS_UBIFS_COMPR_LZO, - MKFS_UBIFS_COMPR_ZLIB, -+ MKFS_UBIFS_COMPR_XZ, - }; - - int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len, ---- a/mkfs.ubifs/Makefile -+++ b/mkfs.ubifs/Makefile -@@ -6,21 +6,33 @@ ALL_SOURCES=*.[ch] hashtable/*.[ch] - - TARGETS = mkfs.ubifs - -+MKFS_UBIFS_OBJS = $(addprefix $(BUILDDIR)/,\ -+ crc16.o lpt.o compr.o devtable.o \ -+ hashtable/hashtable.o hashtable/hashtable_itr.o) -+ - ifeq ($(WITHOUT_LZO), 1) - CPPFLAGS += -DWITHOUT_LZO - else - LZOLDLIBS = -llzo2 - endif - --LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) -lm -luuid -L$(BUILDDIR)/../ubi-utils/ -lubi -+ifeq ($(WITHOUT_XZ), 1) -+ CPPFLAGS += -DWITHOUT_XZ -+else -+ifneq ($(LZMA_STATIC_LIB),) -+ MKFS_UBIFS_OBJS += $(LZMA_STATIC_LIB) -+else -+ XZLDLIBS = -llzma -+endif -+endif -+ -+LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) $(XZLDLIBS) -lm -luuid -L$(BUILDDIR)/../ubi-utils/ -lubi - LDLIBS_mkfs.ubifs += -L$(BUILDDIR)/../lib -lmtd --LDLIBS_mkfs.ubifs += $(ZLIBLDFLAGS) $(LZOLDFLAGS) -+LDLIBS_mkfs.ubifs += $(ZLIBLDFLAGS) $(LZOLDFLAGS) $(XZLDFLAGS) - - include ../common.mk - --$(BUILDDIR)/mkfs.ubifs: $(addprefix $(BUILDDIR)/,\ -- crc16.o lpt.o compr.o devtable.o \ -- hashtable/hashtable.o hashtable/hashtable_itr.o) -+$(BUILDDIR)/mkfs.ubifs: $(MKFS_UBIFS_OBJS) - - clean:: - rm -f $(BUILDDIR)/hashtable/*.o cscope.* ---- a/mkfs.ubifs/mkfs.ubifs.c -+++ b/mkfs.ubifs/mkfs.ubifs.c -@@ -98,6 +98,9 @@ struct ubifs_info info_; - static struct ubifs_info *c = &info_; - static libubi_t ubi; - -+static int force_compr_set; -+static int force_compr; -+ - /* Debug levels are: 0 (none), 1 (statistics), 2 (files) ,3 (more details) */ - int debug_level; - int verbose; -@@ -132,7 +135,7 @@ static struct inum_mapping **hash_table; - /* Inode creation sequence number */ - static unsigned long long creat_sqnum; - --static const char *optstring = "d:r:m:o:D:h?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQq"; -+static const char *optstring = "d:r:m:o:D:h?vVe:c:g:f:Fp:k:x:X:y:j:R:l:j:UQq"; - - static const struct option longopts[] = { - {"root", 1, NULL, 'r'}, -@@ -149,6 +152,7 @@ static const struct option longopts[] = - {"reserved", 1, NULL, 'R'}, - {"compr", 1, NULL, 'x'}, - {"favor-percent", 1, NULL, 'X'}, -+ {"force-compr", 1, NULL, 'y'}, - {"fanout", 1, NULL, 'f'}, - {"space-fixup", 0, NULL, 'F'}, - {"keyhash", 1, NULL, 'k'}, -@@ -178,11 +182,13 @@ static const char *helptext = - "-o, --output=FILE output to FILE\n" - "-j, --jrn-size=SIZE journal size\n" - "-R, --reserved=SIZE how much space should be reserved for the super-user\n" --"-x, --compr=TYPE compression type - \"lzo\", \"favor_lzo\", \"zlib\" or\n" --" \"none\" (default: \"lzo\")\n" -+"-x, --compr=TYPE default compression type - \"lzo\", \"favor_lzo\",\n" -+" \"zlib\" or \"none\" (default: \"lzo\")\n" - "-X, --favor-percent may only be used with favor LZO compression and defines\n" - " how many percent better zlib should compress to make\n" - " mkfs.ubifs use zlib instead of LZO (default 20%)\n" -+"-y, --force-compr=TYPE force to build the fs with different compression -\n" -+" \"lzo\", \"zlib\" or \"none\"\n" - "-f, --fanout=NUM fanout NUM (default: 8)\n" - "-F, --space-fixup file-system free space has to be fixed up on first mount\n" - " (requires kernel version 3.0 or greater)\n" -@@ -530,6 +536,43 @@ static int open_ubi(const char *node) - return 0; - } - -+static const char *get_compr_str(int compr) -+{ -+ switch (compr) { -+ case UBIFS_COMPR_LZO: -+ return "lzo"; -+ case UBIFS_COMPR_ZLIB: -+ return "zlib"; -+ case UBIFS_COMPR_XZ: -+ return "xz"; -+ case UBIFS_COMPR_NONE: -+ return "none"; -+ } -+ -+ return "unknown"; -+} -+ -+static int get_compr_option(char *opt, int *compr_type, int *favor_lzo) -+{ -+ *compr_type = UBIFS_COMPR_LZO; -+ -+ if (favor_lzo) -+ *favor_lzo = 0; -+ -+ if (favor_lzo && strcmp(optarg, "favor_lzo") == 0) -+ *favor_lzo = 1; -+ else if (strcmp(optarg, "zlib") == 0) -+ *compr_type = UBIFS_COMPR_ZLIB; -+ else if (strcmp(optarg, "xz") == 0) -+ *compr_type = UBIFS_COMPR_XZ; -+ else if (strcmp(optarg, "none") == 0) -+ *compr_type = UBIFS_COMPR_NONE; -+ else if (strcmp(optarg, "lzo") != 0) -+ return -1; -+ -+ return 0; -+} -+ - static int get_options(int argc, char**argv) - { - int opt, i; -@@ -649,14 +692,13 @@ static int get_options(int argc, char**a - return err_msg("bad key hash"); - break; - case 'x': -- if (strcmp(optarg, "favor_lzo") == 0) -- c->favor_lzo = 1; -- else if (strcmp(optarg, "zlib") == 0) -- c->default_compr = UBIFS_COMPR_ZLIB; -- else if (strcmp(optarg, "none") == 0) -- c->default_compr = UBIFS_COMPR_NONE; -- else if (strcmp(optarg, "lzo") != 0) -- return err_msg("bad compressor name"); -+ if (get_compr_option(optarg, &c->default_compr, -+ &c->favor_lzo)) -+ return err_msg("bad compressor name '%s'", -+ optarg); -+ if (c->default_compr == UBIFS_COMPR_XZ) -+ return err_msg("'%s' can't be used as default compressor", -+ optarg); - break; - case 'X': - c->favor_percent = strtol(optarg, &endp, 0); -@@ -665,6 +707,12 @@ static int get_options(int argc, char**a - return err_msg("bad favor LZO percent '%s'", - optarg); - break; -+ case 'y': -+ if (get_compr_option(optarg, &force_compr, NULL)) -+ return err_msg("bad forced compressor name '%s'", -+ optarg); -+ force_compr_set = 1; -+ break; - case 'j': - c->max_bud_bytes = get_bytes(optarg); - if (c->max_bud_bytes <= 0) -@@ -749,6 +797,9 @@ static int get_options(int argc, char**a - c->min_io_size = 8; - c->rp_size = add_space_overhead(c->rp_size); - -+ if (force_compr_set == 0) -+ force_compr = c->default_compr; -+ - if (verbose) { - printf("mkfs.ubifs\n"); - printf("\troot: %s\n", root); -@@ -758,17 +809,10 @@ static int get_options(int argc, char**a - printf("\toutput: %s\n", output); - printf("\tjrn_size: %llu\n", c->max_bud_bytes); - printf("\treserved: %llu\n", c->rp_size); -- switch (c->default_compr) { -- case UBIFS_COMPR_LZO: -- printf("\tcompr: lzo\n"); -- break; -- case UBIFS_COMPR_ZLIB: -- printf("\tcompr: zlib\n"); -- break; -- case UBIFS_COMPR_NONE: -- printf("\tcompr: none\n"); -- break; -- } -+ printf("\tcompr: %s\n", get_compr_str(c->default_compr)); -+ if (force_compr_set) -+ printf("\tforced compr: %s\n", -+ get_compr_str(force_compr)); - printf("\tkeyhash: %s\n", (c->key_hash == key_r5_hash) ? - "r5" : "test"); - printf("\tfanout: %d\n", c->fanout); -@@ -1353,7 +1397,7 @@ static int add_file(const char *path_nam - use_compr = UBIFS_COMPR_LZO; - else - #endif -- use_compr = c->default_compr; -+ use_compr = force_compr; - compr_type = compress_data(buf, bytes_read, &dn->data, - &out_len, use_compr); - dn->compr_type = cpu_to_le16(compr_type); ---- a/mkfs.ubifs/mkfs.ubifs.h -+++ b/mkfs.ubifs/mkfs.ubifs.h -@@ -77,6 +77,9 @@ - #if MKFS_UBIFS_COMPR_ZLIB != UBIFS_COMPR_ZLIB - #error MKFS_UBIFS_COMPR_ZLIB != UBIFS_COMPR_ZLIB - #endif -+#if MKFS_UBIFS_COMPR_XZ != UBIFS_COMPR_XZ -+#error MKFS_UBIFS_COMPR_XZ != UBIFS_COMPR_XZ -+#endif - - extern int verbose; - extern int debug_level; ---- a/mkfs.ubifs/ubifs-media.h -+++ b/mkfs.ubifs/ubifs-media.h -@@ -303,6 +303,7 @@ enum { - UBIFS_COMPR_NONE, - UBIFS_COMPR_LZO, - UBIFS_COMPR_ZLIB, -+ UBIFS_COMPR_XZ, - UBIFS_COMPR_TYPES_CNT, - }; - diff --git a/tools/mtd-utils/patches/200-libubigen-add-ubigen_write_terminator-function.patch b/tools/mtd-utils/patches/200-libubigen-add-ubigen_write_terminator-function.patch new file mode 100644 index 00000000000..d95ece184c7 --- /dev/null +++ b/tools/mtd-utils/patches/200-libubigen-add-ubigen_write_terminator-function.patch @@ -0,0 +1,89 @@ +--- a/lib/libubigen.c ++++ b/lib/libubigen.c +@@ -122,8 +122,9 @@ int ubigen_add_volume(const struct ubige + return 0; + } + +-void ubigen_init_ec_hdr(const struct ubigen_info *ui, +- struct ubi_ec_hdr *hdr, long long ec) ++static void __ubigen_init_ec_hdr(const struct ubigen_info *ui, ++ struct ubi_ec_hdr *hdr, long long ec, ++ int eof) + { + uint32_t crc; + +@@ -136,10 +137,22 @@ void ubigen_init_ec_hdr(const struct ubi + hdr->data_offset = cpu_to_be32(ui->data_offs); + hdr->image_seq = cpu_to_be32(ui->image_seq); + ++ if (eof) { ++ hdr->padding1[0] = 'E'; ++ hdr->padding1[1] = 'O'; ++ hdr->padding1[2] = 'F'; ++ } ++ + crc = mtd_crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC); + hdr->hdr_crc = cpu_to_be32(crc); + } + ++void ubigen_init_ec_hdr(const struct ubigen_info *ui, ++ struct ubi_ec_hdr *hdr, long long ec) ++{ ++ __ubigen_init_ec_hdr(ui, hdr, ec, 0); ++} ++ + void ubigen_init_vid_hdr(const struct ubigen_info *ui, + const struct ubigen_vol_info *vi, + struct ubi_vid_hdr *hdr, int lnum, +@@ -307,6 +320,39 @@ int ubigen_write_layout_vol(const struct + } + + free(outbuf); ++ return 0; ++ ++out_free: ++ free(outbuf); ++ return -1; ++} ++ ++int ubigen_write_eof_markers(const struct ubigen_info *ui, long long ec, ++ int count, int out_fd) ++{ ++ char *outbuf; ++ int peb_size = ui->peb_size; ++ ++ outbuf = malloc(peb_size); ++ if (!outbuf) { ++ sys_errmsg("cannot allocate %d bytes of memory", peb_size); ++ return -1; ++ } ++ ++ memset(outbuf, 0xFF, peb_size); ++ __ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec, 1); ++ ++ while (count) { ++ if (write(out_fd, outbuf, peb_size) != peb_size) { ++ sys_errmsg("cannot write %d bytes to the output file", ++ peb_size); ++ goto out_free; ++ } ++ ++ count--; ++ } ++ ++ free(outbuf); + return 0; + + out_free: +--- a/include/libubigen.h ++++ b/include/libubigen.h +@@ -188,6 +188,9 @@ int ubigen_write_layout_vol(const struct + long long ec1, long long ec2, + struct ubi_vtbl_record *vtbl, int fd); + ++int ubigen_write_eof_markers(const struct ubigen_info *ui, long long ec, ++ int count, int out_fd); ++ + #ifdef __cplusplus + } + #endif diff --git a/tools/mtd-utils/patches/201-ubinize-add-terminator-support.patch b/tools/mtd-utils/patches/201-ubinize-add-terminator-support.patch new file mode 100644 index 00000000000..0da28b71f2e --- /dev/null +++ b/tools/mtd-utils/patches/201-ubinize-add-terminator-support.patch @@ -0,0 +1,68 @@ +--- a/ubi-utils/ubinize.c ++++ b/ubi-utils/ubinize.c +@@ -60,6 +60,8 @@ static const char optionsstr[] = + " (default is 1)\n" + "-Q, --image-seq=<num> 32-bit UBI image sequence number to use\n" + " (by default a random number is picked)\n" ++"-E, --eof-markers=<num> number of eof-markers to put at the end of the\n" ++" output image\n" + "-v, --verbose be verbose\n" + "-h, --help print help message\n" + "-V, --version print program version\n\n"; +@@ -79,6 +81,7 @@ static const struct option long_options[ + { .name = "erase-counter", .has_arg = 1, .flag = NULL, .val = 'e' }, + { .name = "ubi-ver", .has_arg = 1, .flag = NULL, .val = 'x' }, + { .name = "image-seq", .has_arg = 1, .flag = NULL, .val = 'Q' }, ++ { .name = "eof-markers", .has_arg = 1, .flag = NULL, .val = 'E' }, + { .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, +@@ -98,6 +101,7 @@ struct args { + uint32_t image_seq; + int verbose; + dictionary *dict; ++ int eof_markers; + }; + + static struct args args = { +@@ -116,7 +120,7 @@ static int parse_opt(int argc, char * co + int key, error = 0; + unsigned long int image_seq; + +- key = getopt_long(argc, argv, "o:p:m:s:O:e:x:Q:vhV", long_options, NULL); ++ key = getopt_long(argc, argv, "o:p:m:s:O:e:x:Q:E:vhV", long_options, NULL); + if (key == -1) + break; + +@@ -176,6 +180,12 @@ static int parse_opt(int argc, char * co + args.image_seq = image_seq; + break; + ++ case 'E': ++ args.eof_markers = simple_strtoul(optarg, &error); ++ if (error) ++ return errmsg("bad number of eof-markers: \"%s\"", optarg); ++ break; ++ + case 'v': + args.verbose = 1; + break; +@@ -559,6 +569,18 @@ int main(int argc, char * const argv[]) + printf("\n"); + } + ++ if (args.eof_markers) { ++ verbose(args.verbose, "writing %d eof-marker blocks", ++ args.eof_markers); ++ ++ err = ubigen_write_eof_markers(&ui, args.ec, args.eof_markers, ++ args.out_fd); ++ if (err) { ++ errmsg("cannot write eof-marker blocks"); ++ goto out_free; ++ } ++ } ++ + verbose(args.verbose, "writing layout volume"); + + err = ubigen_write_layout_vol(&ui, 0, 1, args.ec, args.ec, vtbl, args.out_fd); diff --git a/tools/mtd-utils/patches/320-mkfs.jffs2-SOURCE_DATE_EPOCH.patch b/tools/mtd-utils/patches/320-mkfs.jffs2-SOURCE_DATE_EPOCH.patch new file mode 100644 index 00000000000..8e580595769 --- /dev/null +++ b/tools/mtd-utils/patches/320-mkfs.jffs2-SOURCE_DATE_EPOCH.patch @@ -0,0 +1,60 @@ +--- a/jffsX-utils/mkfs.jffs2.c ++++ b/jffsX-utils/mkfs.jffs2.c +@@ -109,7 +109,7 @@ static char *rootdir = default_rootdir; + static int verbose = 0; + static int squash_uids = 0; + static int squash_perms = 0; +-static int fake_times = 0; ++static time_t fixed_timestamp = -1; + int target_endian = __BYTE_ORDER; + + static uint32_t find_hardlink(struct filesystem_entry *e) +@@ -250,8 +250,8 @@ static struct filesystem_entry *add_host + mode &= ~(S_ISUID | S_ISGID); + } + } +- if (fake_times) { +- timestamp = 0; ++ if (fixed_timestamp != -1) { ++ timestamp = fixed_timestamp; + } + + entry = xcalloc(1, sizeof(struct filesystem_entry)); +@@ -1557,6 +1557,20 @@ static void parse_image(void){ + close(in_fd); + } + ++static void set_source_date_epoch() { ++ char *env = getenv("SOURCE_DATE_EPOCH"); ++ char *endptr = env; ++ errno = 0; ++ if (env && *env) { ++ fixed_timestamp = strtoull(env, &endptr, 10); ++ if (errno || (endptr && *endptr != '\0')) { ++ fprintf(stderr, "Invalid SOURCE_DATE_EPOCH"); ++ exit(1); ++ } ++ } ++} ++ ++ + int main(int argc, char **argv) + { + int c, opt; +@@ -1575,6 +1589,7 @@ int main(int argc, char **argv) + warn_page_size = 1; /* warn user if page size not 4096 */ + + jffs2_compressors_init(); ++ set_source_date_epoch(); + + while ((opt = getopt_long(argc, argv, + "D:d:r:s:o:qUPfh?vVe:lbp::nc:m:x:X:Lty:i:", long_options, &c)) >= 0) +@@ -1625,7 +1640,7 @@ int main(int argc, char **argv) + break; + + case 'f': +- fake_times = 1; ++ fixed_timestamp = 0; + break; + + case 'h': diff --git a/tools/mtools/Makefile b/tools/mtools/Makefile new file mode 100644 index 00000000000..64be6ae01bb --- /dev/null +++ b/tools/mtools/Makefile @@ -0,0 +1,38 @@ +# +# Copyright (C) 2012-2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=mtools +PKG_VERSION:=4.0.18 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@GNU/$(PKG_NAME) +PKG_HASH:=30d408d039b4cedcd04fbf824c89b0ff85dcbb6f71f13d2d8d65abb3f58cacc3 +PKG_CAT:=zcat + +HOST_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/host-build.mk + +HOST_CONFIGURE_VARS += \ + ac_cv_header_iconv_h=no + +define Host/Compile + $(MAKE) -C $(HOST_BUILD_DIR) mcopy mmd +endef + +define Host/Install + $(INSTALL_BIN) $(HOST_BUILD_DIR)/mcopy $(STAGING_DIR_HOST)/bin/ + $(INSTALL_BIN) $(HOST_BUILD_DIR)/mmd $(STAGING_DIR_HOST)/bin/ +endef + +define Host/Clean + rm -f $(STAGING_DIR_HOST)/bin/mcopy + rm -f $(STAGING_DIR_HOST)/bin/mmd +endef + +$(eval $(call HostBuild)) diff --git a/tools/mtools/patches/100-compile_fix.patch b/tools/mtools/patches/100-compile_fix.patch new file mode 100644 index 00000000000..698e1560298 --- /dev/null +++ b/tools/mtools/patches/100-compile_fix.patch @@ -0,0 +1,19 @@ +--- a/sysincludes.h ++++ b/sysincludes.h +@@ -101,14 +101,8 @@ typedef void *caddr_t; + #if defined __GNUC__ && defined __STDC__ + /* gcc -traditional doesn't have PACKED, UNUSED and NORETURN */ + # define PACKED __attribute__ ((packed)) +-# if __GNUC__ == 2 && __GNUC_MINOR__ > 6 || __GNUC__ >= 3 +-/* gcc 2.6.3 doesn't have "unused" */ /* mool */ +-# define UNUSED(x) x __attribute__ ((unused));x +-# define UNUSEDP __attribute__ ((unused)) +-# else +-# define UNUSED(x) x +-# define UNUSEDP /* */ +-# endif ++# define UNUSED(x) x ++# define UNUSEDP /* */ + # define NORETURN __attribute__ ((noreturn)) + #else + # define UNUSED(x) x diff --git a/tools/padjffs2/Makefile b/tools/padjffs2/Makefile index a949ac06282..0a583b8e1a8 100644 --- a/tools/padjffs2/Makefile +++ b/tools/padjffs2/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2011 OpenWrt.org +# Copyright (C) 2011-2012 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -18,6 +18,10 @@ define Host/Prepare find $(HOST_BUILD_DIR) -name .svn | $(XARGS) rm -rf endef +define Host/Compile + $(MAKE) -C $(HOST_BUILD_DIR) +endef + define Host/Configure endef diff --git a/tools/padjffs2/src/Makefile b/tools/padjffs2/src/Makefile index fe1a7aa628d..45da8e5dbc3 100644 --- a/tools/padjffs2/src/Makefile +++ b/tools/padjffs2/src/Makefile @@ -9,7 +9,7 @@ all: padjffs2 $(CC) $(CFLAGS) $(WFLAGS) -c -o $@ $< padjffs2: $(padjffs2-objs) - $(CC) -o $@ $(padjffs2-objs) + $(CC) $(LDFLAGS) -o $@ $(padjffs2-objs) clean: rm -f padjffs2 *.o diff --git a/tools/padjffs2/src/padjffs2.c b/tools/padjffs2/src/padjffs2.c index 58d99140d92..6308292431e 100644 --- a/tools/padjffs2/src/padjffs2.c +++ b/tools/padjffs2/src/padjffs2.c @@ -15,11 +15,18 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <stdbool.h> #include <sys/types.h> #include <sys/stat.h> static char *progname; +static unsigned int xtra_offset; static unsigned char eof_mark[4] = {0xde, 0xad, 0xc0, 0xde}; +static unsigned char jffs2_pad_be[] = "\x19\x85\x20\x04\x04\x00\x00\x00\xc4\x94\xdb\xf4"; +static unsigned char jffs2_pad_le[] = "\x85\x19\x04\x20\x00\x00\x00\x04\xa8\xfb\xa0\xb4"; +static unsigned char *pad = eof_mark; +static int pad_len = sizeof(eof_mark); +static bool pad_to_stdout = false; #define ERR(fmt, ...) do { \ fflush(0); \ @@ -41,6 +48,7 @@ static int pad_image(char *name, uint32_t pad_mask) { char *buf; int fd; + int outfd; ssize_t in_len; ssize_t out_len; int ret = -1; @@ -61,8 +69,15 @@ static int pad_image(char *name, uint32_t pad_mask) if (in_len < 0) goto close; + if (!pad_to_stdout) + outfd = fd; + else + outfd = STDOUT_FILENO; + memset(buf, '\xff', BUF_SIZE); + in_len += xtra_offset; + out_len = in_len; while (pad_mask) { uint32_t mask; @@ -83,7 +98,7 @@ static int pad_image(char *name, uint32_t pad_mask) pad_mask &= ~mask; } - printf("padding image to %08x\n", (unsigned int) in_len); + fprintf(stderr, "padding image to %08x\n", (unsigned int) in_len - xtra_offset); while (out_len < in_len) { ssize_t len; @@ -92,7 +107,7 @@ static int pad_image(char *name, uint32_t pad_mask) if (len > BUF_SIZE) len = BUF_SIZE; - t = write(fd, buf, len); + t = write(outfd, buf, len); if (t != len) { ERRS("Unable to write to %s", name); goto close; @@ -102,12 +117,12 @@ static int pad_image(char *name, uint32_t pad_mask) } /* write out the JFFS end-of-filesystem marker */ - t = write(fd, eof_mark, 4); - if (t != 4) { + t = write(outfd, pad, pad_len); + if (t != pad_len) { ERRS("Unable to write to %s", name); goto close; } - out_len += 4; + out_len += pad_len; } ret = 0; @@ -120,31 +135,71 @@ out: return ret; } +static int usage(void) +{ + fprintf(stderr, + "Usage: %s file [<options>] [pad0] [pad1] [padN]\n" + "Options:\n" + " -x <offset>: Add an extra offset for padding data\n" + " -J: Use a fake big-endian jffs2 padding element instead of EOF\n" + " This is used to work around broken boot loaders that\n" + " try to parse the entire firmware area as one big jffs2\n" + " -j: (like -J, but little-endian instead of big-endian)\n" + " -c: write padding to stdout\n" + "\n", + progname); + return EXIT_FAILURE; +} + int main(int argc, char* argv[]) { + char *image; uint32_t pad_mask; int ret = EXIT_FAILURE; int err; - int i; + int ch, i; progname = basename(argv[0]); - if (argc < 2) { - fprintf(stderr, - "Usage: %s file [pad0] [pad1] [padN]\n", - progname); - goto out; - } + if (argc < 2) + return usage(); + + image = argv[1]; + argv++; + argc--; pad_mask = 0; - for (i = 2; i < argc; i++) + while ((ch = getopt(argc, argv, "x:Jjc")) != -1) { + switch (ch) { + case 'x': + xtra_offset = strtoul(optarg, NULL, 0); + fprintf(stderr, "assuming %u bytes offset\n", + xtra_offset); + break; + case 'J': + pad = jffs2_pad_be; + pad_len = sizeof(jffs2_pad_be) - 1; + break; + case 'j': + pad = jffs2_pad_le; + pad_len = sizeof(jffs2_pad_le) - 1; + break; + case 'c': + pad_to_stdout = true; + break; + default: + return usage(); + } + } + + for (i = optind; i < argc; i++) pad_mask |= strtoul(argv[i], NULL, 0) * 1024; if (pad_mask == 0) pad_mask = (4 * 1024) | (8 * 1024) | (64 * 1024) | (128 * 1024); - err = pad_image(argv[1], pad_mask); + err = pad_image(image, pad_mask); if (err) goto out; diff --git a/tools/patch-cmdline/Makefile b/tools/patch-image/Makefile index 9a3f971ef7e..6f2900b96ce 100644 --- a/tools/patch-cmdline/Makefile +++ b/tools/patch-image/Makefile @@ -1,25 +1,28 @@ # -# Copyright (C) 2007 OpenWrt.org +# Copyright (C) 2007-2012 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. # include $(TOPDIR)/rules.mk -PKG_NAME:=patch-cmdline +PKG_NAME:=patch-image include $(INCLUDE_DIR)/host-build.mk define Host/Compile - $(HOSTCC) $(HOST_CFLAGS) -include endian.h -o $(HOST_BUILD_DIR)/$(PKG_NAME) src/$(PKG_NAME).c + $(HOSTCC) $(HOST_CFLAGS) -include endian.h -o $(HOST_BUILD_DIR)/patch-cmdline src/patch-cmdline.c + $(HOSTCC) $(HOST_CFLAGS) -include endian.h -o $(HOST_BUILD_DIR)/patch-dtb src/patch-dtb.c endef define Host/Install $(CP) $(HOST_BUILD_DIR)/patch-cmdline $(STAGING_DIR_HOST)/bin/ + $(CP) $(HOST_BUILD_DIR)/patch-dtb $(STAGING_DIR_HOST)/bin/ endef define Host/Clean rm -f $(STAGING_DIR_HOST)/bin/patch-cmdline + rm -f $(STAGING_DIR_HOST)/bin/patch-dtb endef $(eval $(call HostBuild)) diff --git a/tools/patch-cmdline/src/patch-cmdline.c b/tools/patch-image/src/patch-cmdline.c index 571f848d81c..8d1fce9172c 100644 --- a/tools/patch-cmdline/src/patch-cmdline.c +++ b/tools/patch-image/src/patch-cmdline.c @@ -1,7 +1,7 @@ /* * patch-cmdline.c - patch the kernel command line on rb532 * - * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> + * Copyright (C) 2006 Felix Fietkau <nbd@nbd.name> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -35,10 +35,16 @@ int main(int argc, char **argv) { int fd, found = 0, len, ret = -1; char *ptr, *p; + unsigned int search_space; - if (argc != 3) { - fprintf(stderr, "Usage: %s <file> <cmdline>\n", argv[0]); + if (argc <= 2 || argc > 4) { + fprintf(stderr, "Usage: %s <file> <cmdline> [size]\n", argv[0]); goto err1; + } else if (argc == 3) { + fprintf(stdout, "search space used is default of 16KB\n"); + search_space = SEARCH_SPACE; + } else { + search_space = atoi(argv[3]); } len = strlen(argv[2]); if (len + 9 > CMDLINE_MAX) { @@ -47,12 +53,12 @@ int main(int argc, char **argv) } if (((fd = open(argv[1], O_RDWR)) < 0) || - (ptr = (char *) mmap(0, SEARCH_SPACE + CMDLINE_MAX, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == (void *) (-1)) { + (ptr = (char *) mmap(0, search_space + CMDLINE_MAX, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == (void *) (-1)) { fprintf(stderr, "Could not open kernel image"); goto err2; } - for (p = ptr; p < (ptr + SEARCH_SPACE); p += 4) { + for (p = ptr; p < (ptr + search_space); p += 4) { if (memcmp(p, "CMDLINE:", 8) == 0) { found = 1; p += 8; diff --git a/tools/patch-image/src/patch-dtb.c b/tools/patch-image/src/patch-dtb.c new file mode 100644 index 00000000000..a94da3fa415 --- /dev/null +++ b/tools/patch-image/src/patch-dtb.c @@ -0,0 +1,103 @@ +/* + * patch-dtb.c - patch a dtb into an image + * + * Copyright (C) 2006 Felix Fietkau <nbd@nbd.name> + * Copyright (C) 2012 John Crispin <blogic@openwrt.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * based on patch-cmdline.c + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <string.h> + +#define DTB_MAX (16 * 1024) + +int main(int argc, char **argv) +{ + int fd, fddtb, found = 0, len, ret = -1; + char *ptr, *ptrdtb, *p; + struct stat s; + unsigned int search_space , dtb_max_size; + + if (argc <= 2 || argc > 4) { + fprintf(stderr, "Usage: %s <file> <dtb> [size]\n", argv[0]); + goto err1; + } else if (argc == 3) { + fprintf(stdout, "DT size used is default of 16KB\n"); + search_space = dtb_max_size = DTB_MAX; + } else { + search_space = dtb_max_size = atoi(argv[3]); + } + + if (stat(argv[2], &s)) { + fprintf(stderr, "DTB not found\n"); + goto err1; + } + + len = s.st_size; + if (len + 8 > dtb_max_size) { + fprintf(stderr, "DTB too big\n"); + goto err1; + } + + if (((fddtb = open(argv[2], O_RDONLY)) < 0) || + (ptrdtb = (char *) mmap(0, dtb_max_size, PROT_READ, MAP_SHARED, fddtb, 0)) == (void *) (-1)) { + fprintf(stderr, "Could not open DTB"); + goto err2; + } + + if (((fd = open(argv[1], O_RDWR)) < 0) || + (ptr = (char *) mmap(0, search_space + dtb_max_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == (void *) (-1)) { + fprintf(stderr, "Could not open kernel image"); + goto err3; + } + + for (p = ptr; p < (ptr + search_space); p += 4) { + if (memcmp(p, "OWRTDTB:", 8) == 0) { + found = 1; + p += 8; + break; + } + } + if (!found) { + fprintf(stderr, "DTB marker not found!\n"); + goto err4; + } + + memset(p, 0, dtb_max_size - 8); + memcpy(p, ptrdtb, len); + msync(p, len, MS_SYNC|MS_INVALIDATE); + ret = 0; + +err4: + munmap((void *) ptr, len); +err3: + if (fd > 0) + close(fd); + munmap((void *) ptrdtb, len); +err2: + if (fddtb > 0) + close(fddtb); +err1: + return ret; +} diff --git a/tools/patch/Makefile b/tools/patch/Makefile new file mode 100644 index 00000000000..4c4c09bc088 --- /dev/null +++ b/tools/patch/Makefile @@ -0,0 +1,23 @@ +# +# Copyright (C) 2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=patch +PKG_VERSION:=2.7.6 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=@GNU/patch +PKG_HASH:=ac610bda97abe0d9f6b7c963255a11dcb196c25e337c61f94e4778d632f1d8fd + +HOST_BUILD_PARALLEL := 1 + +include $(INCLUDE_DIR)/host-build.mk + +HOSTCC := $(HOSTCC_NOCACHE) +HOSTCXX := $(HOSTCXX_NOCACHE) + +$(eval $(call HostBuild)) diff --git a/tools/patchelf/Makefile b/tools/patchelf/Makefile new file mode 100644 index 00000000000..1728fba2770 --- /dev/null +++ b/tools/patchelf/Makefile @@ -0,0 +1,26 @@ +# +# Copyright (C) 2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=patchelf +PKG_VERSION:=0.9 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=http://nixos.org/releases/patchelf/patchelf-$(PKG_VERSION) +PKG_HASH:=a0f65c1ba148890e9f2f7823f4bedf7ecad5417772f64f994004f59a39014f83 + +HOST_BUILD_PARALLEL:=1 +HOST_FIXUP:=autoreconf + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Install + $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin + $(INSTALL_BIN) $(HOST_BUILD_DIR)/src/patchelf $(STAGING_DIR_HOST)/bin/patchelf +endef + +$(eval $(call HostBuild)) diff --git a/tools/pkg-config/Makefile b/tools/pkg-config/Makefile index e7d2982f7f4..17a8737be16 100644 --- a/tools/pkg-config/Makefile +++ b/tools/pkg-config/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006 OpenWrt.org +# Copyright (C) 2006-2016 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,17 +7,26 @@ include $(TOPDIR)/rules.mk PKG_NAME:=pkg-config -PKG_VERSION:=0.25 +PKG_VERSION:=0.29.2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=http://pkgconfig.freedesktop.org/releases/ -PKG_MD5SUM:=a3270bab3f4b69b7dc6dbdacbcae9745 +PKG_SOURCE_URL:=https://pkgconfig.freedesktop.org/releases/ +PKG_HASH:=6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591 + +HOST_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/host-build.mk +unexport PKG_CONFIG + +HOST_CONFIGURE_ARGS += --with-internal-glib + +ifeq ($(HOST_OS),Darwin) +HOST_LDFLAGS += -framework CoreFoundation -framework Carbon +endif + define Host/Install - $(MAKE) -C $(HOST_BUILD_DIR) \ - install + $(MAKE) -C $(HOST_BUILD_DIR) install mv $(STAGING_DIR_HOST)/bin/pkg-config $(STAGING_DIR_HOST)/bin/pkg-config.real $(INSTALL_BIN) ./files/pkg-config $(STAGING_DIR_HOST)/bin/pkg-config endef diff --git a/tools/pkg-config/patches/100-disable_compat_cmd.patch b/tools/pkg-config/patches/100-disable_compat_cmd.patch deleted file mode 100644 index 990784045ec..00000000000 --- a/tools/pkg-config/patches/100-disable_compat_cmd.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/parse.c -+++ b/parse.c -@@ -1187,15 +1187,12 @@ try_command (const char *command) - Package * - get_compat_package (const char *name) - { --#ifdef G_OS_WIN32 -- /* There has never been any of these legacy *-config scripts on -- * Windows as far as I know. No use trying to execute them, will -- * only confuse users to see the "blabla is not recognized as an -- * internal or external command, operable program or batch file" -- * messages. -+ /* -+ * We don't need this compatibility stuff on a system -+ * that is free of legacy stuff - */ - return NULL; --#else -+#if 0 - - Package *pkg; - diff --git a/tools/ppl/Makefile b/tools/ppl/Makefile deleted file mode 100644 index 46c966d827c..00000000000 --- a/tools/ppl/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright (C) 2009 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -include $(TOPDIR)/rules.mk - -PKG_NAME:=ppl -PKG_VERSION:=0.10.2 - -PKG_SOURCE_URL:=ftp://gcc.gnu.org/pub/gcc/infrastructure -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_MD5SUM:=e7dd265afdeaea81f7e87a72b182d875 - -HOST_FIXUP:=autoreconf - -include $(INCLUDE_DIR)/host-build.mk - -unexport CFLAGS - -HOST_CONFIGURE_ARGS += \ - --enable-static \ - --disable-shared - -define Host/Configure - (cd $(HOST_BUILD_DIR)/$(3); \ - $(HOST_CONFIGURE_CMD) \ - $(HOST_CONFIGURE_VARS) \ - $(HOST_CONFIGURE_ARGS); \ - ) -endef - - -$(eval $(call HostBuild)) diff --git a/tools/ppl/patches/001-gmp_5_fix.patch b/tools/ppl/patches/001-gmp_5_fix.patch deleted file mode 100644 index bd7fad3f411..00000000000 --- a/tools/ppl/patches/001-gmp_5_fix.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Roberto Bagnara <bagnara@cs.unipr.it> -Date: Sat, 9 Jan 2010 15:32:08 +0000 (+0100) -Subject: Added support for GMP 5.0. -X-Git-Url: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl%2Fppl.git;a=commitdiff_plain;h=9c19bc2b318a35016e0189f9552c98910be37f53 - -Added support for GMP 5.0. ---- - -diff --git a/m4/ac_check_gmp.m4 b/m4/ac_check_gmp.m4 -index 60cecdc..15acb18 100644 ---- a/m4/ac_check_gmp.m4 -+++ b/m4/ac_check_gmp.m4 -@@ -71,6 +71,10 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[ - #GMP version 4.1.3 or higher is required - #endif - -+#ifndef BITS_PER_MP_LIMB -+#define BITS_PER_MP_LIMB GMP_LIMB_BITS -+#endif -+ - int - main() { - std::string header_version; -@@ -97,11 +101,11 @@ main() { - return 1; - } - -- if (sizeof(mp_limb_t)*CHAR_BIT != GMP_LIMB_BITS -- || GMP_LIMB_BITS != mp_bits_per_limb) { -+ if (sizeof(mp_limb_t)*CHAR_BIT != BITS_PER_MP_LIMB -+ || BITS_PER_MP_LIMB != mp_bits_per_limb) { - std::cerr - << "GMP header (gmp.h) and library (ligmp.*) bits-per-limb mismatch:\n" -- << "header gives " << __GMP_BITS_PER_MP_LIMB << ";\n" -+ << "header gives " << BITS_PER_MP_LIMB << ";\n" - << "library gives " << mp_bits_per_limb << ".\n" - << "This probably means you are on a bi-arch system and\n" - << "you are compiling with the wrong header or linking with\n" diff --git a/tools/qemu/Makefile b/tools/qemu/Makefile index c0d587b243f..d63ab3482eb 100644 --- a/tools/qemu/Makefile +++ b/tools/qemu/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2010 OpenWrt.org +# Copyright (C) 2010-2012 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,26 +7,31 @@ include $(TOPDIR)/rules.mk PKG_NAME:=qemu -PKG_VERSION:=0.13.0 +PKG_CPE_ID:=cpe:/a:qemu:qemu +PKG_VERSION:=0.14.1 PKG_RELEASE:=1 -PKG_SOURCE_URL:=http://download.savannah.gnu.org/releases/qemu/ +PKG_SOURCE_URL:=@SAVANNAH/qemu PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_MD5SUM:=397a0d665da8ba9d3b9583629f3d6421 +PKG_HASH:=33ceae3fbe516f2cbb151dc98d16c8ccfec74b1056674ad715e75a2f7fed45c3 include $(INCLUDE_DIR)/host-build.mk -HOST_CFLAGS += -I$(STAGING_DIR_HOST)/include/e2fsprogs - -define Host/Configure - (cd $(HOST_BUILD_DIR); \ - CFLAGS="$(HOST_CFLAGS)" \ - LDFLAGS="$(HOST_LDFLAGS)" \ - $(HOST_CONFIGURE_CMD) \ - --extra-cflags="$(HOST_CFLAGS)" \ - --enable-uuid \ - ) -endef +HOST_CFLAGS += \ + -I$(STAGING_DIR_HOST)/include/e2fsprogs \ + -DAES_cbc_encrypt=QEMU_AES_cbc_encrypt \ + -DAES_decrypt=QEMU_AES_decrypt \ + -DAES_encrypt=QEMU_AES_encrypt \ + -DAES_set_decrypt_key=QEMU_AES_set_decrypt_key \ + -DAES_set_encrypt_key=QEMU_AES_set_encrypt_key + +HOST_CONFIGURE_VARS := \ + CFLAGS="$(HOST_CFLAGS)" \ + LDFLAGS="$(HOST_LDFLAGS)" + +HOST_CONFIGURE_ARGS := \ + --extra-cflags="$(HOST_CFLAGS)" \ + --enable-uuid define Host/Compile $(MAKE) -C $(HOST_BUILD_DIR) qemu-img diff --git a/tools/qemu/patches/010-freebsd-fix.patch b/tools/qemu/patches/010-freebsd-fix.patch deleted file mode 100644 index 1fc09120964..00000000000 --- a/tools/qemu/patches/010-freebsd-fix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/block/sheepdog.c -+++ b/block/sheepdog.c -@@ -12,7 +12,7 @@ - #include <windows.h> - #include <winsock2.h> - #include <ws2tcpip.h> --#else -+#elifndef __FreeBSD__ - #include <netdb.h> - #include <netinet/tcp.h> - diff --git a/tools/quilt/Makefile b/tools/quilt/Makefile index 510d8f6fd5a..d0532b5984e 100644 --- a/tools/quilt/Makefile +++ b/tools/quilt/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006 -2010 OpenWrt.org +# Copyright (C) 2006-2015 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,21 +7,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=quilt -PKG_VERSION:=0.48 +PKG_VERSION:=0.65 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=http://download.savannah.gnu.org/releases/$(PKG_NAME) -PKG_MD5SUM:=f77adda60039ffa753f3c584a286f12b +PKG_SOURCE_URL:=@SAVANNAH/quilt +PKG_HASH:=f6cbc788e5cbbb381a3c6eab5b9efce67c776a8662a7795c7432fd27aa096819 include $(INCLUDE_DIR)/host-build.mk -GETOPT:=$(shell which getopt) - -HOST_CONFIGURE_ARGS += \ - --with-patch=$(PATCH) \ - --with-find=$(FIND) \ - --with-getopt=$(GETOPT) - define Host/Configure cd $(HOST_BUILD_DIR) && autoconf $(call Host/Configure/Default) @@ -29,7 +22,7 @@ define Host/Configure endef define Host/Compile - $(MAKE) -C $(HOST_BUILD_DIR) SHELL="$(BASH)" all lib/backup-files + $(MAKE) -C $(HOST_BUILD_DIR) SHELL="$(BASH)" all endef define Host/Install diff --git a/tools/quilt/patches/000-relocatable.patch b/tools/quilt/patches/000-relocatable.patch index f8110236a6d..0e0eb7380ce 100644 --- a/tools/quilt/patches/000-relocatable.patch +++ b/tools/quilt/patches/000-relocatable.patch @@ -1,69 +1,59 @@ --- a/bin/quilt.in +++ b/bin/quilt.in -@@ -7,9 +7,15 @@ - # See the COPYING and AUTHORS files for more details. +@@ -15,14 +15,22 @@ unset POSIXLY_CORRECT + unset GREP_OPTIONS export TEXTDOMAIN=quilt -export TEXTDOMAINDIR=@LOCALEDIR@ --: ${QUILT_DIR=@QUILT_DIR@} ${QUILT_LIB=@QUILT_LIB@} -+if test -n "$STAGING_DIR"; then -+ export TEXTDOMAINDIR="$STAGING_DIR/../host/share/locale" -+ : ${QUILT_DIR=$STAGING_DIR/../host/share/quilt} ${QUILT_LIB=$STAGING_DIR/../host/lib/quilt} +-: ${QUILT_DIR=@QUILT_DIR@} ++if test -n "$STAGING_DIR_HOST"; then ++ export TEXTDOMAINDIR="$STAGING_DIR_HOST/share/locale" ++ : ${QUILT_DIR=$STAGING_DIR_HOST/share/quilt} ${QUILT_LIB=$STAGING_DIR_HOST/lib/quilt} ++ : ${QUILT_ETC=$STAGING_DIR_HOST/etc} +else + export TEXTDOMAINDIR=@LOCALEDIR@ -+ : ${QUILT_DIR=@QUILT_DIR@} ${QUILT_LIB=@QUILT_LIB@} ++ : ${QUILT_DIR=@QUILT_DIR@} ++ : ${QUILT_ETC=@ETCDIR@} +fi + - export QUILT_DIR QUILT_LIB + export QUILT_DIR if [ -z "$QUILTRC" ] + then +- for QUILTRC in $HOME/.quiltrc @ETCDIR@/quilt.quiltrc; do ++ for QUILTRC in $HOME/.quiltrc $QUILT_ETC/quilt.quiltrc; do + [ -e $QUILTRC ] && break + done + export QUILTRC --- a/quilt/scripts/edmail.in +++ b/quilt/scripts/edmail.in -@@ -29,7 +29,7 @@ BEGIN { - } - - setlocale(LC_MESSAGES, ""); --bindtextdomain("quilt", "@LOCALEDIR@"); -+bindtextdomain("quilt", $ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/locale' : "@LOCALEDIR@"); - textdomain("quilt"); +@@ -1,4 +1,6 @@ +-#! @PERL@ -w ++#! @PERL@ ++ ++use warnings; - sub _($) { ---- a/quilt/scripts/inspect.in -+++ b/quilt/scripts/inspect.in -@@ -6,7 +6,11 @@ + # RFCs important for this script: # - # See the COPYING and AUTHORS files for more details. - --: ${QUILT_DIR=@QUILT_DIR@} -+if test -n "$STAGING_DIR"; then -+ : ${QUILT_DIR="$STAGING_DIR/../host/share/quilt"} -+else -+ : ${QUILT_DIR=@QUILT_DIR@} -+fi - - if ! [ -r $QUILT_DIR/scripts/patchfns ] - then ---- a/quilt/scripts/parse-patch.in -+++ b/quilt/scripts/parse-patch.in -@@ -34,7 +34,7 @@ BEGIN { +@@ -29,7 +31,7 @@ BEGIN { } setlocale(LC_MESSAGES, ""); -bindtextdomain("quilt", "@LOCALEDIR@"); -+bindtextdomain("quilt", $ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/locale' : "@LOCALEDIR@"); ++bindtextdomain("quilt", $ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . '/share/locale' : "@LOCALEDIR@"); textdomain("quilt"); sub _($) { --- a/quilt/scripts/patchfns.in +++ b/quilt/scripts/patchfns.in -@@ -10,7 +10,11 @@ +@@ -8,7 +8,11 @@ # See the COPYING and AUTHORS files for more details. export TEXTDOMAIN=quilt -export TEXTDOMAINDIR=@LOCALEDIR@ -+if [ -n "$STAGING_DIR" ]; then -+ export TEXTDOMAINDIR="$STAGING_DIR/../host/share/locale" ++if [ -n "$STAGING_DIR_HOST" ]; then ++ export TEXTDOMAINDIR="$STAGING_DIR_HOST/share/locale" +else + export TEXTDOMAINDIR=@LOCALEDIR@ +fi @@ -72,12 +62,109 @@ : ${LC_MESSAGES:=$LANG} --- a/quilt/scripts/remove-trailing-ws.in +++ b/quilt/scripts/remove-trailing-ws.in -@@ -31,7 +31,7 @@ BEGIN { +@@ -1,4 +1,6 @@ +-#! @PERL@ -w ++#! @PERL@ ++ ++use warnings; + + # Remove trailing whitespace from modified lines in working files. + # +@@ -31,7 +33,7 @@ BEGIN { } setlocale(LC_MESSAGES, ""); -bindtextdomain("quilt", "@LOCALEDIR@"); -+bindtextdomain("quilt", $ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/locale' : "@LOCALEDIR@"); ++bindtextdomain("quilt", $ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . '/share/locale' : "@LOCALEDIR@"); textdomain("quilt"); sub _($) { +--- a/Makefile.in ++++ b/Makefile.in +@@ -21,8 +21,8 @@ COLUMN := @COLUMN@ + GETOPT := @GETOPT@ + CP := @CP@ + DATE := @DATE@ +-PERL := @PERL@ +-BASH := @BASH@ ++PERL := /usr/bin/env perl ++BASH := /usr/bin/env bash + SHELL:= @BASH@ # It does not work if dash is used as a shell, for example + GREP := @GREP@ + TAIL := @TAIL@ +@@ -32,7 +32,7 @@ AWK := @AWK@ + FIND := @FIND@ + XARGS := @XARGS@ + DIFF := @DIFF@ +-PATCH := @PATCH@ ++PATCH := /usr/bin/env patch + MKTEMP := @MKTEMP@ + MSGMERGE := @MSGMERGE@ + MSGFMT := @MSGFMT@ +@@ -48,8 +48,8 @@ USE_NLS := @USE_NLS@ + STAT_HARDLINK := @STAT_HARDLINK@ + PATCH_WRAPPER := @PATCH_WRAPPER@ + +-COMPAT_SYMLINKS := @COMPAT_SYMLINKS@ +-COMPAT_PROGRAMS := @COMPAT_PROGRAMS@ ++COMPAT_SYMLINKS := ++COMPAT_PROGRAMS := + + default: all + +--- a/quilt/scripts/backup-files.in ++++ b/quilt/scripts/backup-files.in +@@ -53,7 +53,12 @@ usage () + " + } + +-: ${QUILT_DIR=@QUILT_DIR@} ++if test -n "$STAGING_DIR_HOST"; then ++ : ${QUILT_DIR="$STAGING_DIR_HOST/share/quilt"} ++else ++ : ${QUILT_DIR=@QUILT_DIR@} ++fi ++ + . $QUILT_DIR/scripts/utilfns + + ensure_nolinks() +--- a/bin/guards.in ++++ b/bin/guards.in +@@ -1,4 +1,6 @@ +-#!@PERL@ -w ++#!@PERL@ ++ ++use warnings; + + # This script is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License version 2 as +--- a/compat/date.in ++++ b/compat/date.in +@@ -1,4 +1,6 @@ +-#! @PERL@ -w ++#! @PERL@ ++ ++use warnings; + + # This script is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License version 2 as +--- a/compat/getopt.in ++++ b/compat/getopt.in +@@ -1,4 +1,6 @@ +-#! @PERL@ -w ++#! @PERL@ ++ ++use warnings; + + # This script is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License version 2 as +--- a/quilt/scripts/dependency-graph.in ++++ b/quilt/scripts/dependency-graph.in +@@ -1,4 +1,6 @@ +-#!@PERL@ -w ++#!@PERL@ ++ ++use warnings; + + # This script is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License version 2 as diff --git a/tools/quilt/patches/001-fix_compile.patch b/tools/quilt/patches/001-fix_compile.patch index 51a4f5e206b..c829515f83d 100644 --- a/tools/quilt/patches/001-fix_compile.patch +++ b/tools/quilt/patches/001-fix_compile.patch @@ -1,7 +1,7 @@ --- a/Makefile.in +++ b/Makefile.in -@@ -273,13 +273,10 @@ $(patsubst %.in,%,$(wildcard bin/*.in qu - lib/backup-files.o :: Makefile +@@ -272,13 +272,10 @@ $(patsubst %.in,%,$(wildcard bin/*.in qu + @$(if $(filter $@,$(NON_EXEC_IN)),,chmod +x $@) configure : configure.ac aclocal.m4 - autoconf @@ -14,5 +14,5 @@ - @false + @touch $@ - compat_leftover := $(filter-out $(COMPAT),$(shell $(FIND) compat -maxdepth 1 -type f -perm +111)) + compat_leftover := $(filter-out $(COMPAT),$(shell $(FIND) compat -type f -perm -0100)) diff --git a/tools/quilt/patches/100-patch_2.6.1_version.patch b/tools/quilt/patches/100-patch_2.6.1_version.patch deleted file mode 100644 index 1e9ed75df1c..00000000000 --- a/tools/quilt/patches/100-patch_2.6.1_version.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/configure.ac -+++ b/configure.ac -@@ -274,7 +274,11 @@ fi - AC_MSG_CHECKING([the version of $PATCH]) - if $PATCH --version 2> /dev/null | grep GNU >/dev/null; then - set -- `$PATCH --version 2> /dev/null` -- patch_version=$2 -+ if test x$1 = xGNU ; then -+ patch_version=$3 -+ else -+ patch_version=$2 -+ fi - AC_MSG_RESULT($patch_version) - saved_IFS=$IFS; IFS='.' - set -- $patch_version diff --git a/tools/scons/Makefile b/tools/scons/Makefile new file mode 100644 index 00000000000..fc325bff02a --- /dev/null +++ b/tools/scons/Makefile @@ -0,0 +1,35 @@ +# +# Copyright (C) 2011-2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=scons +PKG_VERSION:=3.0.1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@SF/scons \ + http://fossies.org/linux/misc/ +PKG_HASH:=24475e38d39c19683bc88054524df018fe6949d70fbd4c69e298d39a0269f173 + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Configure +endef + +define Host/Compile +endef + +define Host/Install + ./files/pywrap.sh $(HOST_BUILD_DIR)/setup.py install --prefix=$(STAGING_DIR_HOST) + rm -f $(STAGING_DIR_HOST)/bin/scons*.py + for bin in $(STAGING_DIR_HOST)/bin/scons*; do \ + mv "$$$$bin" "$$$$bin.py"; \ + cp ./files/pywrap.sh "$$$$bin"; \ + done +endef + +$(eval $(call HostBuild)) diff --git a/tools/scons/files/pywrap.sh b/tools/scons/files/pywrap.sh new file mode 100755 index 00000000000..f62f590e0bc --- /dev/null +++ b/tools/scons/files/pywrap.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +case "${0##*/}" in + pywrap.sh) arg1="";; + *) arg1="$0.py" ;; +esac + +for bin in python python2 python2.7 python2.6 python2.5 python2.4; do + case "$($bin -V 2>&1)" in + "Python 2"*) exec $bin $arg1 "$@" ;; + esac +done + +echo "Unable to find a Python 2.x interpreter for executing ${arg1:+$arg1 }$@ !" >&2 +exit 1 diff --git a/tools/scons/patches/001-platform_env.patch b/tools/scons/patches/001-platform_env.patch new file mode 100644 index 00000000000..2be31470c27 --- /dev/null +++ b/tools/scons/patches/001-platform_env.patch @@ -0,0 +1,11 @@ +--- a/engine/SCons/Platform/__init__.py ++++ b/engine/SCons/Platform/__init__.py +@@ -65,6 +65,8 @@ def platform_default(): + care about the machine architecture. + """ + osname = os.name ++ if 'PLATFORM' in os.environ: ++ return os.environ['PLATFORM'] + if osname == 'java': + osname = os._osType + if osname == 'posix': diff --git a/tools/sdimage/Makefile b/tools/sdimage/Makefile new file mode 100644 index 00000000000..44d671414fb --- /dev/null +++ b/tools/sdimage/Makefile @@ -0,0 +1,34 @@ +# +# Copyright (C) 2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=imx-uuc +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/mhei/fsl-imx-uuc.git +PKG_SOURCE_DATE:=2016-01-10 +PKG_SOURCE_VERSION:=d395b310b6c0f41ab1302242a639e7d0d7767207 +PKG_MIRROR_HASH:=d67ec9d509201511bc7cba9f7551baa729361817f97390f7c5cbb99b5a7b89b1 + +PKG_LICENSE:=GPL-2.0+ +PKG_LICENSE_FILES:=LICENSE + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Configure +endef + +define Host/Install + $(INSTALL_BIN) $(HOST_BUILD_DIR)/sdimage $(STAGING_DIR_HOST)/bin/sdimage +endef + +define Host/Clean + rm -f $(STAGING_DIR_HOST)/bin/sdimage +endef + +$(eval $(call HostBuild)) diff --git a/tools/sed/Makefile b/tools/sed/Makefile index 9ccfc7b9d3b..834519b7375 100644 --- a/tools/sed/Makefile +++ b/tools/sed/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006-2010 OpenWrt.org +# Copyright (C) 2006-2013 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,18 +7,31 @@ include $(TOPDIR)/rules.mk PKG_NAME:=sed -PKG_VERSION:=4.2.1 +PKG_VERSION:=4.5 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNU/$(PKG_NAME) -PKG_MD5SUM:=7d310fbd76e01a01115075c1fd3f455a -PKG_CAT:=bzcat +PKG_HASH:=7aad73c8839c2bdadca9476f884d2953cdace9567ecd0d90f9959f229d146b40 export SED:= +HOST_BUILD_PARALLEL:=1 + +HOSTCC := $(HOSTCC_NOCACHE) +HOSTCXX := $(HOSTCXX_NOCACHE) + include $(INCLUDE_DIR)/host-build.mk +HOST_CONFIGURE_ARGS += \ + --disable-acl \ + --disable-nls \ + +HOST_CONFIGURE_VARS += \ + ac_cv_search_setfilecon=no \ + ac_cv_header_selinux_context_h=no \ + ac_cv_header_selinux_selinux_h=no \ + define Host/Compile - $(MAKE) -C $(HOST_BUILD_DIR) SHELL="$(BASH)" + +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR) SHELL="$(BASH)" endef define Host/Install diff --git a/tools/sparse/Makefile b/tools/sparse/Makefile new file mode 100644 index 00000000000..959016b1323 --- /dev/null +++ b/tools/sparse/Makefile @@ -0,0 +1,24 @@ +# +# Copyright (C) 2014 Qualcomm-Atheros Inc. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=sparse + +PKG_VERSION:=0.5.2 +PKG_HASH:=4632b7b74af72214247f982f976ba44206933bab3a2717e09df166fb5b8abe7a +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=@KERNEL/software/devel/sparse/dist/ + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Install + $(INSTALL_BIN) $(HOST_BUILD_DIR)/sparse $(STAGING_DIR_HOST)/bin +endef + +$(eval $(call HostBuild)) diff --git a/tools/squashfs/Makefile b/tools/squashfs/Makefile index 473c5265108..385cf69d9d7 100644 --- a/tools/squashfs/Makefile +++ b/tools/squashfs/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006 OpenWrt.org +# Copyright (C) 2006-2012 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,11 +7,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=squashfs +PKG_CPE_ID:=cpe:/a:phillip_lougher:squashfs PKG_VERSION:=3.0 PKG_SOURCE:=$(PKG_NAME)$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@SF/squashfs -PKG_MD5SUM:=9fd05d0bfbb712f5fb95edafea5bc733 +PKG_HASH:=39dbda43cf118536deb746c7730b468702d514a19f4cfab73b710e32908ddf20 PKG_CAT:=zcat HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)$(PKG_VERSION) @@ -20,6 +21,9 @@ include $(INCLUDE_DIR)/host-build.mk define Host/Compile $(MAKE) -C $(HOST_BUILD_DIR)/squashfs-tools \ + CC="$(HOSTCC)" \ + CFLAGS="$(HOST_CFLAGS) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -I." \ + CXX="$(CXX)" \ LZMAPATH=$(STAGING_DIR_HOST)/lib \ mksquashfs-lzma unsquashfs-lzma endef diff --git a/tools/squashfs/patches/100-lzma.patch b/tools/squashfs/patches/100-lzma.patch index e3b2a3a89c1..73f6a4e0552 100644 --- a/tools/squashfs/patches/100-lzma.patch +++ b/tools/squashfs/patches/100-lzma.patch @@ -1,6 +1,6 @@ --- a/squashfs-tools/Makefile +++ b/squashfs-tools/Makefile -@@ -7,6 +8,9 @@ all: mksquashfs unsquashfs +@@ -7,6 +7,9 @@ all: mksquashfs unsquashfs mksquashfs: mksquashfs.o read_fs.o sort.o $(CC) mksquashfs.o read_fs.o sort.o -lz -o $@ @@ -10,7 +10,7 @@ mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h -@@ -16,4 +20,9 @@ sort.o: sort.c squashfs_fs.h global.h so +@@ -16,4 +19,9 @@ sort.o: sort.c squashfs_fs.h global.h so unsquashfs: unsquashfs.o $(CC) unsquashfs.o -lz -o $@ diff --git a/tools/squashfs/patches/110-no_nonstatic_inline.patch b/tools/squashfs/patches/110-no_nonstatic_inline.patch new file mode 100644 index 00000000000..8e288f336e0 --- /dev/null +++ b/tools/squashfs/patches/110-no_nonstatic_inline.patch @@ -0,0 +1,11 @@ +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -1347,7 +1347,7 @@ struct inode_info *lookup_inode(struct s + } + + +-inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, struct inode_info *inode_info, void *data, struct dir_info *dir) ++static inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, struct inode_info *inode_info, void *data, struct dir_info *dir) + { + if((dir->count % DIR_ENTRIES) == 0) + if((dir->list = realloc(dir->list, (dir->count + DIR_ENTRIES) * sizeof(struct dir_ent *))) == NULL) diff --git a/tools/squashfs/patches/120-add-fixed-timestamp-support.patch b/tools/squashfs/patches/120-add-fixed-timestamp-support.patch new file mode 100644 index 00000000000..e2f4bb2e049 --- /dev/null +++ b/tools/squashfs/patches/120-add-fixed-timestamp-support.patch @@ -0,0 +1,79 @@ +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -117,6 +117,9 @@ unsigned int inode_bytes = 0, inode_size + char *data_cache = NULL; + unsigned int cache_bytes = 0, cache_size = 0, inode_count = 0; + ++/* override all timestamps */ ++time_t fixed_time = -1; ++ + /* in memory directory data */ + #define I_COUNT_SIZE 128 + #define DIR_ENTRIES 32 +@@ -1554,6 +1557,11 @@ void dir_scan(squashfs_inode *inode, cha + perror(buffer); + return; + } ++ ++ /* override timestamp of lstat if fixed_time is given */ ++ if(fixed_time != -1) ++ inode_info->buf.st_mtime = fixed_time; ++ + if(sorted) + sort_files_and_write(dir_info); + dir_scan2(inode, dir_info); +@@ -1582,6 +1590,10 @@ struct dir_info *dir_scan1(char *pathnam + perror(buffer); + continue; + } ++ ++ if(fixed_time != -1) ++ buf.st_mtime = fixed_time; ++ + if(excluded(filename, &buf)) + continue; + +@@ -1621,6 +1633,9 @@ int dir_scan2(squashfs_inode *inode, str + char *dir_name = dir_ent->name; + unsigned int inode_number = ((buf->st_mode & S_IFMT) == S_IFDIR) ? dir_ent->inode->inode_number : dir_ent->inode->inode_number + dir_inode_no; + ++ if(fixed_time != -1) ++ buf->st_mtime = fixed_time; ++ + if(dir_ent->inode->inode == SQUASHFS_INVALID_BLK) { + switch(buf->st_mode & S_IFMT) { + case S_IFREG: +@@ -1898,6 +1913,16 @@ int main(int argc, char *argv[]) + exit(1); + } + } ++ } else if(strcmp(argv[i], "-fixed-time") == 0) { ++ if(++i == argc) { ++ ERROR("%s: -fixed-time missing a timestamp\n", argv[0]); ++ exit(1); ++ } ++ fixed_time = strtoll(argv[i], &b, 10); ++ if(*b != '\0') { ++ ERROR("%s: -fixed-time has an invalid number\n", argv[0]); ++ exit(1); ++ } + } else if(strcmp(argv[i], "-noI") == 0 || + strcmp(argv[i], "-noInodeCompression") == 0) + noI = TRUE; +@@ -1967,6 +1992,7 @@ printOptions: + ERROR("-all-root\t\tmake all files owned by root\n"); + ERROR("-force-uid uid\t\tset all file uids to uid\n"); + ERROR("-force-gid gid\t\tset all file gids to gid\n"); ++ ERROR("-fixed-time timestamp\tset all timestamps to timestamp\n"); + ERROR("-le\t\t\tcreate a little endian filesystem\n"); + ERROR("-be\t\t\tcreate a big endian filesystem\n"); + ERROR("-nopad\t\t\tdo not pad filesystem to a multiple of 4K\n"); +@@ -2190,7 +2216,7 @@ printOptions: + sBlk.block_size = block_size; + sBlk.block_log = block_log; + sBlk.flags = SQUASHFS_MKFLAGS(noI, noD, check_data, noF, no_fragments, always_use_fragments, duplicate_checking); +- sBlk.mkfs_time = time(NULL); ++ sBlk.mkfs_time = fixed_time != -1 ? fixed_time : time(NULL); + + restore_filesystem: + write_fragment(); diff --git a/tools/squashfs/patches/130-include_sysmacros.patch b/tools/squashfs/patches/130-include_sysmacros.patch new file mode 100644 index 00000000000..f0149d6f65f --- /dev/null +++ b/tools/squashfs/patches/130-include_sysmacros.patch @@ -0,0 +1,20 @@ +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -30,6 +30,7 @@ + #include <unistd.h> + #include <stdio.h> + #include <sys/types.h> ++#include <sys/sysmacros.h> + #include <sys/stat.h> + #include <fcntl.h> + #include <errno.h> +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -25,6 +25,7 @@ + #define FALSE 0 + #include <stdio.h> + #include <sys/types.h> ++#include <sys/sysmacros.h> + #include <sys/stat.h> + #include <fcntl.h> + #include <errno.h> diff --git a/tools/squashfs4/Makefile b/tools/squashfs4/Makefile index 04a5456f6c2..409b1b5a238 100644 --- a/tools/squashfs4/Makefile +++ b/tools/squashfs4/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2009 OpenWrt.org +# Copyright (C) 2009-2012 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,11 +7,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=squashfs4 +PKG_CPE_ID:=cpe:/a:phillip_lougher:squashfs PKG_VERSION:=4.2 PKG_SOURCE:=squashfs$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@SF/squashfs -PKG_MD5SUM:=1b7a781fb4cf8938842279bd3e8ee852 +PKG_HASH:=d9e0195aa922dbb665ed322b9aaa96e04a476ee650f39bbeadb0d00b24022e96 PKG_CAT:=zcat HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/squashfs$(PKG_VERSION) @@ -19,6 +20,7 @@ HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/squashfs$(PKG_VERSION) include $(INCLUDE_DIR)/host-build.mk define Host/Compile + +$(HOST_MAKE_VARS) \ $(MAKE) -C $(HOST_BUILD_DIR)/squashfs-tools \ XZ_SUPPORT=1 \ LZMA_XZ_SUPPORT=1 \ diff --git a/tools/squashfs4/patches/130-include_sysmacros.patch b/tools/squashfs4/patches/130-include_sysmacros.patch new file mode 100644 index 00000000000..e8845130ef7 --- /dev/null +++ b/tools/squashfs4/patches/130-include_sysmacros.patch @@ -0,0 +1,20 @@ +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -33,6 +33,7 @@ + #include <stddef.h> + #include <sys/time.h> + #include <sys/types.h> ++#include <sys/sysmacros.h> + #include <sys/stat.h> + #include <fcntl.h> + #include <errno.h> +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -30,6 +30,7 @@ + #include "xattr.h" + + #include <sys/types.h> ++#include <sys/sysmacros.h> + + struct cache *fragment_cache, *data_cache; + struct queue *to_reader, *to_deflate, *to_writer, *from_writer; diff --git a/tools/squashfs4/patches/160-expose_lzma_xz_options.patch b/tools/squashfs4/patches/160-expose_lzma_xz_options.patch index d6063969d27..9e1c1fbb1ea 100644 --- a/tools/squashfs4/patches/160-expose_lzma_xz_options.patch +++ b/tools/squashfs4/patches/160-expose_lzma_xz_options.patch @@ -40,6 +40,7 @@ + + +struct lzma_opts { ++ uint32_t dict_size; + uint32_t flags; +#define LZMA_OPT_FLT_MASK 0xffff +#define LZMA_OPT_PRE_OFF 16 @@ -53,7 +54,6 @@ +#define LZMA_OPT_PB_OFF 6 +#define LZMA_OPT_PB_MASK (0x7 << LZMA_OPT_PB_OFF) + uint16_t fb; -+ uint32_t dict_size; +}; + +#if __BYTE_ORDER == __BIG_ENDIAN @@ -637,7 +637,7 @@ } name = argv[1]; -@@ -76,190 +73,50 @@ static int xz_options(char *argv[], int +@@ -76,190 +73,50 @@ static int xz_options(char *argv[], int } if(bcj[i].name == NULL) { fprintf(stderr, "xz: -Xbcj unrecognised " @@ -864,7 +864,7 @@ SQUASHFS_METADATA_SIZE; filter[0].filter[0].id = LZMA_FILTER_LZMA2; -@@ -323,14 +181,25 @@ static int xz_compress(void *strm, void +@@ -323,14 +181,25 @@ static int xz_compress(void *strm, void lzma_ret res = 0; struct xz_stream *stream = strm; struct filter *selected = NULL; diff --git a/tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch b/tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch index ad69b190ea9..bc7d6c7a4a0 100644 --- a/tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch +++ b/tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch @@ -16,7 +16,7 @@ #define SQUASHFS_METADATA_LOG 13 --- a/squashfs-tools/unsquashfs.c +++ b/squashfs-tools/unsquashfs.c -@@ -1463,10 +1463,12 @@ int read_super(char *source) +@@ -1464,10 +1464,12 @@ int read_super(char *source) */ read_fs_bytes(fd, SQUASHFS_START, sizeof(struct squashfs_super_block), &sBlk_4); @@ -31,7 +31,7 @@ sBlk_4.s_minor == 0) { s_ops.squashfs_opendir = squashfs_opendir_4; s_ops.read_fragment = read_fragment_4; -@@ -1479,7 +1481,11 @@ int read_super(char *source) +@@ -1480,7 +1482,11 @@ int read_super(char *source) /* * Check the compression type */ @@ -44,7 +44,7 @@ return TRUE; } -@@ -1494,8 +1500,10 @@ int read_super(char *source) +@@ -1495,8 +1501,10 @@ int read_super(char *source) * Check it is a SQUASHFS superblock */ swap = 0; @@ -57,7 +57,7 @@ squashfs_super_block_3 sblk; ERROR("Reading a different endian SQUASHFS filesystem " "on %s\n", source); -@@ -1573,7 +1581,11 @@ int read_super(char *source) +@@ -1574,7 +1582,11 @@ int read_super(char *source) /* * 1.x, 2.x and 3.x filesystems use gzip compression. */ diff --git a/tools/squashfs4/patches/180-openbsd_compat.patch b/tools/squashfs4/patches/180-openbsd_compat.patch new file mode 100644 index 00000000000..4f7afd89cc9 --- /dev/null +++ b/tools/squashfs4/patches/180-openbsd_compat.patch @@ -0,0 +1,24 @@ +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -32,6 +32,9 @@ + #include <stdio.h> + #include <stddef.h> + #include <sys/time.h> ++#if defined(__OpenBSD__) ++#include <sys/param.h> ++#endif + #include <sys/types.h> + #include <sys/sysmacros.h> + #include <sys/stat.h> +--- a/squashfs-tools/unsquashfs.h ++++ b/squashfs-tools/unsquashfs.h +@@ -25,6 +25,9 @@ + #define TRUE 1 + #define FALSE 0 + #include <stdio.h> ++#if defined(__OpenBSD__) ++#include <sys/param.h> ++#endif + #include <sys/types.h> + #include <unistd.h> + #include <stdlib.h> diff --git a/tools/squashfs4/patches/190-no_nonstatic_inline.patch b/tools/squashfs4/patches/190-no_nonstatic_inline.patch new file mode 100644 index 00000000000..8cab1208325 --- /dev/null +++ b/tools/squashfs4/patches/190-no_nonstatic_inline.patch @@ -0,0 +1,36 @@ +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -736,13 +736,13 @@ void cache_block_put(struct file_buffer + + (((char *)A) - data_cache))) + + +-inline void inc_progress_bar() ++static inline void inc_progress_bar() + { + cur_uncompressed ++; + } + + +-inline void update_progress_bar() ++static inline void update_progress_bar() + { + pthread_mutex_lock(&progress_mutex); + pthread_cond_signal(&progress_wait); +@@ -750,7 +750,7 @@ inline void update_progress_bar() + } + + +-inline void waitforthread(int i) ++static inline void waitforthread(int i) + { + TRACE("Waiting for thread %d\n", i); + while(thread[i] != 0) +@@ -3359,7 +3359,7 @@ struct inode_info *lookup_inode(struct s + } + + +-inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, ++static inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, + struct inode_info *inode_info, struct dir_info *dir) + { + if((dir->count % DIR_ENTRIES) == 0) { diff --git a/tools/squashfs4/patches/200-add-fixed-timestamp-option.patch b/tools/squashfs4/patches/200-add-fixed-timestamp-option.patch new file mode 100644 index 00000000000..7411b978449 --- /dev/null +++ b/tools/squashfs4/patches/200-add-fixed-timestamp-option.patch @@ -0,0 +1,82 @@ +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -176,6 +176,9 @@ unsigned int cache_bytes = 0, cache_size + /* inode lookup table */ + squashfs_inode *inode_lookup_table = NULL; + ++/* override all timestamps */ ++time_t fixed_time = -1; ++ + /* in memory directory data */ + #define I_COUNT_SIZE 128 + #define DIR_ENTRIES 32 +@@ -2453,6 +2456,8 @@ again: + restat: + fstat(file, &buf2); + close(file); ++ if (fixed_time != -1) ++ buf2.st_mtime = fixed_time; + if(read_size != buf2.st_size) { + memcpy(buf, &buf2, sizeof(struct stat)); + file_buffer->error = 2; +@@ -3613,7 +3618,7 @@ void dir_scan(squashfs_inode *inode, cha + buf.st_mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR; + buf.st_uid = getuid(); + buf.st_gid = getgid(); +- buf.st_mtime = time(NULL); ++ buf.st_mtime = fixed_time != -1 ? fixed_time : time(NULL); + buf.st_dev = 0; + buf.st_ino = 0; + dir_ent->inode = lookup_inode(&buf); +@@ -3624,6 +3629,8 @@ void dir_scan(squashfs_inode *inode, cha + pathname, strerror(errno)); + return; + } ++ if(fixed_time != -1) ++ buf.st_mtime = fixed_time; + dir_ent->inode = lookup_inode(&buf); + } + +@@ -3678,6 +3685,8 @@ struct dir_info *dir_scan1(char *pathnam + filename, strerror(errno)); + continue; + } ++ if(fixed_time != -1) ++ buf.st_mtime = fixed_time; + + if((buf.st_mode & S_IFMT) != S_IFREG && + (buf.st_mode & S_IFMT) != S_IFDIR && +@@ -3796,7 +3805,7 @@ struct dir_info *dir_scan2(struct dir_in + buf.st_gid = pseudo_ent->dev->gid; + buf.st_rdev = makedev(pseudo_ent->dev->major, + pseudo_ent->dev->minor); +- buf.st_mtime = time(NULL); ++ buf.st_mtime = fixed_time != -1 ? fixed_time : time(NULL); + buf.st_ino = pseudo_ino ++; + + if(pseudo_ent->dev->type == 'f') { +@@ -4675,6 +4684,15 @@ int main(int argc, char *argv[]) + progress = FALSE; + else if(strcmp(argv[i], "-no-exports") == 0) + exportable = FALSE; ++ else if(strcmp(argv[i], "-fixed-time") == 0) { ++ if((++i == argc) || (fixed_time = ++ strtoll(argv[i], &b, 10), *b != '\0')) { ++ ERROR("%s: -fixed-time missing or invalid " ++ "timestamp\n", argv[0]); ++ ++ exit(1); ++ } ++ } + else if(strcmp(argv[i], "-processors") == 0) { + if((++i == argc) || (processors = + strtol(argv[i], &b, 10), *b != '\0')) { +@@ -5315,7 +5333,7 @@ printOptions: + sBlk.flags = SQUASHFS_MKFLAGS(noI, noD, noF, noX, no_fragments, + always_use_fragments, duplicate_checking, exportable, + no_xattrs, comp_opts); +- sBlk.mkfs_time = time(NULL); ++ sBlk.mkfs_time = fixed_time != -1 ? fixed_time : time(NULL); + + restore_filesystem: + if(progress && estimated_uncompressed) { diff --git a/tools/sstrip/Makefile b/tools/sstrip/Makefile index 681e533be43..180bd1743e5 100644 --- a/tools/sstrip/Makefile +++ b/tools/sstrip/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006 OpenWrt.org +# Copyright (C) 2006-2012 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -11,7 +11,7 @@ PKG_NAME:=sstrip include $(INCLUDE_DIR)/host-build.mk define Host/Compile - $(HOSTCC) $(HOST_CFLAGS) -I./include -include endian.h -o $(HOST_BUILD_DIR)/sstrip src/sstrip.c + $(HOSTCC) $(HOST_CFLAGS) -include endian.h -o $(HOST_BUILD_DIR)/sstrip src/sstrip.c endef define Host/Install diff --git a/tools/sstrip/src/sstrip.c b/tools/sstrip/src/sstrip.c index 0508aaac81e..12cf12e0958 100644 --- a/tools/sstrip/src/sstrip.c +++ b/tools/sstrip/src/sstrip.c @@ -59,6 +59,7 @@ #include <unistd.h> #include <fcntl.h> #include <elf.h> +#include <byteswap.h> #ifndef TRUE #define TRUE 1 @@ -103,7 +104,7 @@ static int do_reverse_endian; } else if (sizeof(X) == 8) { \ __res = bswap_64((X)); \ } else { \ - fprintf(stderr, "%s: %s: EGET failed for size %d\n", \ + fprintf(stderr, "%s: %s: EGET failed for size %zu\n", \ progname, filename, sizeof(X)); \ exit(EXIT_FAILURE); \ } \ @@ -124,7 +125,7 @@ static int do_reverse_endian; } else if (sizeof(Y) == 8) { \ Y = bswap_64((uint64_t)(X)); \ } else { \ - fprintf(stderr, "%s: %s: ESET failed for size %d\n", \ + fprintf(stderr, "%s: %s: ESET failed for size %zu\n", \ progname, filename, sizeof(Y)); \ exit(EXIT_FAILURE); \ } while (0) @@ -197,7 +198,7 @@ static int getmemorysize ## CLASS (Elf ## CLASS ## _Ehdr const *ehdr, \ { \ Elf ## CLASS ## _Phdr const *phdr; \ unsigned long size, n; \ - int i; \ + size_t i; \ \ /* Start by setting the size to include the ELF header and the \ * complete program segment header table. \ @@ -230,7 +231,7 @@ static int modifyheaders ## CLASS (Elf ## CLASS ## _Ehdr *ehdr, \ unsigned long newsize) \ { \ Elf ## CLASS ## _Phdr *phdr; \ - int i; \ + size_t i; \ \ /* If the section header table is gone, then remove all references \ * to it in the ELF header. \ diff --git a/tools/tar/Makefile b/tools/tar/Makefile new file mode 100644 index 00000000000..baa431e2db6 --- /dev/null +++ b/tools/tar/Makefile @@ -0,0 +1,31 @@ +# +# Copyright (C) 2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=tar +PKG_CPE_ID:=cpe:/a:gnu:tar +PKG_VERSION:=1.30 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=@GNU/tar +PKG_HASH:=87592b86cb037c554375f5868bdd3cc57748aef38d6cb741c81065f0beac63b7 + +HOST_BUILD_PARALLEL := 1 + +include $(INCLUDE_DIR)/host-build.mk + +HOSTCC := $(HOSTCC_NOCACHE) +HOSTCXX := $(HOSTCXX_NOCACHE) + +HOST_CONFIGURE_ARGS += \ + --without-posix-acls \ + --without-selinux \ + --without-xattrs \ + --disable-acl \ + --disable-nls + +$(eval $(call HostBuild)) diff --git a/tools/tar/patches/100-symlink-force-root-name.patch b/tools/tar/patches/100-symlink-force-root-name.patch new file mode 100644 index 00000000000..93f889761b7 --- /dev/null +++ b/tools/tar/patches/100-symlink-force-root-name.patch @@ -0,0 +1,27 @@ +Force root/root as names for uid0/gid0 instead of using the system +names. This helps make packed download tarballs more reproducible + +Signed-off-by: Felix Fietkau <nbd@nbd.name> +--- +--- a/src/create.c ++++ b/src/create.c +@@ -544,17 +544,8 @@ write_gnu_long_link (struct tar_stat_inf + union block *header; + + header = start_private_header ("././@LongLink", size, 0); +- if (! numeric_owner_option) +- { +- static char *uname, *gname; +- if (!uname) +- { +- uid_to_uname (0, &uname); +- gid_to_gname (0, &gname); +- } +- UNAME_TO_CHARS (uname, header->header.uname); +- GNAME_TO_CHARS (gname, header->header.gname); +- } ++ UNAME_TO_CHARS ("root", header->header.uname); ++ GNAME_TO_CHARS ("root", header->header.gname); + + strcpy (header->buffer + offsetof (struct posix_header, magic), + OLDGNU_MAGIC); diff --git a/tools/tar/patches/110-symlink-force-permissions.patch b/tools/tar/patches/110-symlink-force-permissions.patch new file mode 100644 index 00000000000..6fb799bc0a3 --- /dev/null +++ b/tools/tar/patches/110-symlink-force-permissions.patch @@ -0,0 +1,10 @@ +--- a/src/create.c ++++ b/src/create.c +@@ -1853,6 +1853,7 @@ dump_file0 (struct tar_stat_info *st, ch + #ifdef HAVE_READLINK + else if (S_ISLNK (st->stat.st_mode)) + { ++ st->stat.st_mode |= 0777; /* make permissions portable */ + st->link_name = areadlinkat_with_size (parentfd, name, st->stat.st_size); + if (!st->link_name) + { diff --git a/tools/upslug2/Makefile b/tools/upslug2/Makefile index 6a73853f3c2..42448b0185b 100644 --- a/tools/upslug2/Makefile +++ b/tools/upslug2/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2009 OpenWrt.org +# Copyright (C) 2009-2012 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -13,7 +13,8 @@ PKG_SOURCE_URL:=http://svn.nslu2-linux.org/svnroot/upslug2/trunk PKG_SOURCE_PROTO:=svn PKG_SOURCE_SUBDIR:=upslug2-$(PKG_VERSION) PKG_SOURCE_VERSION:=41 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_MIRROR_HASH:=5c69eae3a2affef8f4f7194cfedfdb9175b04ca433f9ae046c85309b42bdb21e include $(INCLUDE_DIR)/host-build.mk diff --git a/tools/upx/Makefile b/tools/upx/Makefile deleted file mode 100644 index 2f3313ca389..00000000000 --- a/tools/upx/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright (C) 2011 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -include $(TOPDIR)/rules.mk - -PKG_NAME:=upx -PKG_VERSION:=3.07 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-src.tar.bz2 -PKG_SOURCE_URL:=@SF/upx -PKG_MD5SUM:=8186ab103288242f7e8ecad1acd4af03 -PKG_CAT:=bzcat - -HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)-src - -include $(INCLUDE_DIR)/host-build.mk - -define Host/Compile - rm -f $(HOST_BUILD_DIR)/src/.depend - $(MAKE) UPX_LZMADIR="$(BUILD_DIR_HOST)/lzma-4.65" -C $(HOST_BUILD_DIR)/src \ - CXXFLAGS_WERROR= -endef - -define Host/Install - $(CP) $(HOST_BUILD_DIR)/src/upx.out $(STAGING_DIR_HOST)/bin/upx -endef - -define Host/Clean - rm -f $(STAGING_DIR_HOST)/bin/upx -endef - -$(eval $(call HostBuild)) diff --git a/tools/upx/patches/100-lzmaonly.patch b/tools/upx/patches/100-lzmaonly.patch deleted file mode 100644 index a3098b47613..00000000000 --- a/tools/upx/patches/100-lzmaonly.patch +++ /dev/null @@ -1,156 +0,0 @@ ---- a/src/compress.cpp -+++ b/src/compress.cpp -@@ -41,7 +41,7 @@ - if (len == 0) - return adler; - assert(buf != NULL); --#if 0 -+#if !(WITH_UCL) - return adler32(adler, (const Bytef *) buf, len); // zlib - #elif (WITH_UCL) - return ucl_adler32(adler, (const ucl_bytep) buf, len); ---- a/src/conf.h -+++ b/src/conf.h -@@ -179,7 +179,7 @@ - # undef __unix - #endif - --#if !defined(WITH_UCL) -+#if defined(WITH_UCL) - # define WITH_UCL 1 - #endif - #if 0 && !defined(WITH_LZMA) -@@ -645,7 +645,11 @@ - }; - - -+#if (WITH_UCL) - struct ucl_compress_config_t : public REAL_ucl_compress_config_t -+#else -+struct ucl_compress_config_t -+#endif - { - void reset() { memset(this, 0xff, sizeof(*this)); } - }; -@@ -697,7 +701,9 @@ - - struct ucl_compress_result_t - { -+#if (WITH_UCL) - ucl_uint result[16]; -+#endif - - void reset() { memset(this, 0, sizeof(*this)); } - }; ---- a/src/main.cpp -+++ b/src/main.cpp -@@ -618,7 +618,9 @@ - opt->method = -1; - opt->all_filters = true; - opt->filter = -1; -+#if (WITH_UCL) - opt->crp.crp_ucl.m_size = 999999; -+#endif - /* fallthrough */ - case 900: // --best - if (!set_method(-1, 10)) -@@ -709,6 +711,7 @@ - opt->exact = true; - break; - // compression runtime parameters -+#if (WITH_UCL) - case 801: - getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg); - break; -@@ -730,6 +733,7 @@ - case 807: - getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u, arg); - break; -+#endif - case 811: - getoptvar(&opt->crp.crp_lzma.pos_bits, arg); - break; ---- a/src/Makefile -+++ b/src/Makefile -@@ -57,7 +57,10 @@ - INCLUDES += -I$(UPX_UCLDIR)/include - LIBS += $(addprefix -L,$(dir $(wildcard $(UPX_UCLDIR)/libucl$(libext) $(UPX_UCLDIR)/src/.libs/libucl$(libext)))) - endif --LIBS += -lucl -lz -+ifeq ($(WITH_UCL),1) -+LIBS += -lucl -+endif -+LIBS += -lz - # you should set envvar UPX_LZMADIR to point to your unpacked LZMA SDK - include $(top_srcdir)/src/stub/src/c/Makevars.lzma - ifneq ($(UPX_LZMA_VERSION),) ---- a/src/packer.cpp -+++ b/src/packer.cpp -@@ -199,6 +199,7 @@ - if (cconf_parm) - cconf = *cconf_parm; - // cconf options -+#if (WITH_UCL) - if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method)) - { - if (opt->crp.crp_ucl.c_flags != -1) -@@ -216,6 +217,7 @@ - step = 0; - #endif - } -+#endif - if (M_IS_LZMA(ph.method)) - { - oassign(cconf.conf_lzma.pos_bits, opt->crp.crp_lzma.pos_bits); -@@ -250,6 +252,7 @@ - if (r != UPX_E_OK) - throwInternalError("compression failed"); - -+#if (WITH_UCL) - if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method)) - { - const ucl_uint *res = ph.compress_result.result_ucl.result; -@@ -267,6 +270,7 @@ - assert(cconf.conf_ucl.max_match == 0 || cconf.conf_ucl.max_match >= ph.max_match_found); - } - } -+#endif - - //printf("\nPacker::compress: %d/%d: %7d -> %7d\n", ph.method, ph.level, ph.u_len, ph.c_len); - if (!checkCompressionRatio(ph.u_len, ph.c_len)) ---- a/src/p_exe.cpp -+++ b/src/p_exe.cpp -@@ -506,7 +506,9 @@ - Filter ft(ph.level); - // compress (max_match = 8192) - upx_compress_config_t cconf; cconf.reset(); -+#if (WITH_UCL) - cconf.conf_ucl.max_match = MAXMATCH; -+#endif - cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack - compressWithFilters(&ft, 32, &cconf); - ---- a/src/p_ps1.cpp -+++ b/src/p_ps1.cpp -@@ -499,7 +499,9 @@ - - // compress (max_match = 65535) - upx_compress_config_t cconf; cconf.reset(); -+#if (WITH_UCL) - cconf.conf_ucl.max_match = 65535; -+#endif - cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack - compressWithFilters(&ft, sa_cnt, &cconf); - ---- a/src/p_tos.cpp -+++ b/src/p_tos.cpp -@@ -506,7 +506,9 @@ - Filter ft(ph.level); - // compress (max_match = 65535) - upx_compress_config_t cconf; cconf.reset(); -+#if (WITH_UCL) - cconf.conf_ucl.max_match = 65535; -+#endif - cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack - compressWithFilters(&ft, 512, &cconf); - diff --git a/tools/wrt350nv2-builder/Makefile b/tools/wrt350nv2-builder/Makefile index 689fd32a538..a705b6dc8d8 100644 --- a/tools/wrt350nv2-builder/Makefile +++ b/tools/wrt350nv2-builder/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006-2010 OpenWrt.org +# Copyright (C) 2006-2012 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -8,7 +8,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=wrt350nv2-builder -PKG_VERSION:=2.3 +PKG_VERSION:=2.4 +PKG_REVISION:=2 HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/${PKG_NAME}-$(PKG_VERSION) @@ -18,7 +19,8 @@ define Host/Compile $(HOSTCC) $(HOST_CFLAGS) -c src/md5.c -o $(HOST_BUILD_DIR)/md5.o $(HOSTCC) $(HOST_CFLAGS) -c src/ioapi.c -o $(HOST_BUILD_DIR)/ioapi.o $(HOSTCC) $(HOST_CFLAGS) -c src/wrt350nv2-builder.c -o $(HOST_BUILD_DIR)/wrt350nv2-builder.o - $(HOSTCC) $(HOST_CFLAGS) -o $(HOST_BUILD_DIR)/wrt350nv2-builder $(HOST_BUILD_DIR)/wrt350nv2-builder.o $(HOST_BUILD_DIR)/md5.o $(HOST_BUILD_DIR)/ioapi.o + $(HOSTCC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $(HOST_BUILD_DIR)/wrt350nv2-builder \ + $(HOST_BUILD_DIR)/wrt350nv2-builder.o $(HOST_BUILD_DIR)/md5.o $(HOST_BUILD_DIR)/ioapi.o endef define Host/Install diff --git a/tools/wrt350nv2-builder/src/ioapi.h b/tools/wrt350nv2-builder/src/ioapi.h index 7d457baab34..5fa9786148a 100644 --- a/tools/wrt350nv2-builder/src/ioapi.h +++ b/tools/wrt350nv2-builder/src/ioapi.h @@ -35,13 +35,13 @@ extern "C" { #endif -typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); -typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); -typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); -typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); -typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); +typedef voidpf (ZCALLBACK *open_file_func) (voidpf opaque, const char* filename, int mode); +typedef uLong (ZCALLBACK *read_file_func) (voidpf opaque, voidpf stream, void* buf, uLong size); +typedef uLong (ZCALLBACK *write_file_func) (voidpf opaque, voidpf stream, const void* buf, uLong size); +typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream); +typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin); +typedef int (ZCALLBACK *close_file_func) (voidpf opaque, voidpf stream); +typedef int (ZCALLBACK *testerror_file_func) (voidpf opaque, voidpf stream); typedef struct zlib_filefunc_def_s { @@ -57,7 +57,7 @@ typedef struct zlib_filefunc_def_s -void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); +void fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def); #define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) #define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) diff --git a/tools/wrt350nv2-builder/src/wrt350nv2-builder.c b/tools/wrt350nv2-builder/src/wrt350nv2-builder.c index 2ce57234c5f..3ebb40ed511 100644 --- a/tools/wrt350nv2-builder/src/wrt350nv2-builder.c +++ b/tools/wrt350nv2-builder/src/wrt350nv2-builder.c @@ -1,8 +1,8 @@ /* - WRT350Nv2-Builder 2.3 (previously called buildimg) + WRT350Nv2-Builder 2.4 (previously called buildimg) Copyright (C) 2008-2009 Dirk Teurlings <info@upexia.nl> - Copyright (C) 2009-2010 Matthias Buecher (http://www.maddes.net/) + Copyright (C) 2009-2011 Matthias Buecher (http://www.maddes.net/) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,6 +33,9 @@ :u-boot 0 /path/to/u-boot.bin #version 0x2020 + Additionally since v2.4 an already complete image can be used: + :image 0 /path/to/openwrt-wrt350nv2-[squashfs|jffs2-64k].img + args: 1 wrt350nv2.par parameter file describing the image layout 2 wrt350nv2.img output file for linksys style image @@ -62,6 +65,8 @@ https://forum.openwrt.org/viewtopic.php?pid=92928#p92928 Changelog: + v2.4 - added ":image" definition for parameter file, this allows + to use a complete sysupgrade image without any kernel size check v2.3 - allow jffs by adding its magic number (0x8519) added parameter option -i to ignore unknown magic numbers v2.2 - fixed checksum byte calculation for other versions than 0x2019 @@ -92,7 +97,7 @@ // version info -#define VERSION "2.3" +#define VERSION "2.4" char program_info[] = "WRT350Nv2-Builder v%s by Dirk Teurlings <info@upexia.nl> and Matthias Buecher (http://www.maddes.net/)\n"; // verbosity @@ -112,6 +117,7 @@ typedef struct { mtd_info mtd_kernel = { "kernel", 0, 0, NULL, 0L, { 0, 0 } }; mtd_info mtd_rootfs = { "rootfs", 0, 0, NULL, 0L, { 0, 0 } }; +mtd_info mtd_image = { "image", 0, 0, NULL, 0L, { 0, 0 } }; mtd_info mtd_uboot = { "u-boot", 0, 0, NULL, 0L, { 0, 0 } }; #define ROOTFS_END_OFFSET 0x00760000 @@ -281,6 +287,8 @@ int parse_par_file(FILE *f_par) { mtd = &mtd_rootfs; } else if (!strcmp(string1, mtd_uboot.name)) { mtd = &mtd_uboot; + } else if (!strcmp(string1, mtd_image.name)) { + mtd = &mtd_image; } if (!mtd) { @@ -404,20 +412,24 @@ int create_bin_file(char *bin_filename) { // add files if (!exitcode) { - for (i = 1; i <= 3; i++) { + for (i = 1; i <= 4; i++) { addsize = 0; padsize = 0; switch (i) { case 1: - mtd = &mtd_kernel; + mtd = &mtd_image; + padsize = ROOTFS_MIN_OFFSET - mtd->filesize; break; case 2: + mtd = &mtd_kernel; + break; + case 3: mtd = &mtd_rootfs; addsize = mtd->filesize; padsize = ROOTFS_MIN_OFFSET - mtd_kernel.size - mtd->filesize; break; - case 3: + case 4: mtd = &mtd_uboot; addsize = mtd->filesize; break; @@ -723,7 +735,6 @@ int main(int argc, char *argv[]) { int i; mtd_info *mtd; - int mandatory; int noupdate; int sizecheck; int magiccheck; @@ -934,28 +945,30 @@ int main(int argc, char *argv[]) { if ((!exitcode) && (par_filename)) { lprintf(DEBUG, "checking mtd data...\n"); - for (i = 1; i <= 3; i++) { - mandatory = 0; + for (i = 1; i <= 4; i++) { noupdate = 0; sizecheck = 0; magiccheck = 0; switch (i) { case 1: + mtd = &mtd_image; + sizecheck = ROOTFS_END_OFFSET; + magiccheck = 1; + break; + case 2: mtd = &mtd_kernel; - mandatory = 1; sizecheck = mtd_kernel.size - 16; magiccheck = 1; break; - case 2: + case 3: mtd = &mtd_rootfs; mtd->offset = mtd_kernel.size; mtd->size = ROOTFS_END_OFFSET - mtd_kernel.size; - mandatory = 1; sizecheck = PRODUCT_ID_OFFSET - mtd_kernel.size; magiccheck = 1; break; - case 3: + case 4: mtd = &mtd_uboot; mtd->offset = BOOT_ADDR_BASE_OFF; noupdate = 1; @@ -974,10 +987,6 @@ int main(int argc, char *argv[]) { lprintf(DEBUG_LVL2, " checking mtd %s\n", mtd->name); // general checks - if ((mandatory) && (!mtd->filename)) { - exitcode = 1; - printf("mtd %s not specified correctly or at all in parameter file\n", mtd->name); - } // no further checks if no file data present if (!mtd->filename) { @@ -993,14 +1002,15 @@ int main(int argc, char *argv[]) { magicerror = 0; if (magiccheck) { switch (i) { - case 1: // kernel + case 1: // image + case 2: // kernel if (!( ((mtd->magic[0] == 0x27) && (mtd->magic[1] == 0x05)) // uImage )) { magicerror = 1; } break; - case 2: // rootfs + case 3: // rootfs if (!( ((mtd->magic[0] == 0x68) && (mtd->magic[1] == 0x73)) // squashfs || ((mtd->magic[0] == 0x85) && (mtd->magic[1] == 0x19)) // jffs @@ -1024,8 +1034,15 @@ int main(int argc, char *argv[]) { } // mtd specific size check + if (mtd == &mtd_image) { + if (mtd->filesize < 0x00200000) { + exitcode = 1; + printf("mtd %s input file %s too unrealistic small (0x%08lX)\n", mtd->name, mtd->filename, mtd->filesize); + } + } + if (mtd == &mtd_kernel) { - if (mtd->filesize < 0x00050000) { + if (mtd->filesize < 0x00080000) { exitcode = 1; printf("mtd %s input file %s too unrealistic small (0x%08lX)\n", mtd->name, mtd->filename, mtd->filesize); } @@ -1044,6 +1061,25 @@ int main(int argc, char *argv[]) { } } } + + // Check for mandatory parts + if ((!mtd_image.filename) && (!mtd_kernel.filename || !mtd_rootfs.filename)) { + exitcode = 1; + if (mtd_kernel.filename && !mtd_rootfs.filename) { + printf("Kernel without rootfs, either incorrectly specified or not at all in parameter file\n"); + } else if (!mtd_kernel.filename && mtd_rootfs.filename) { + printf("Rootfs without kernel, either incorrectly specified or not at all in parameter file\n"); + } else { + printf("Neither an image nor kernel with rootfs was/were correctly specified or at all in parameter file\n"); + } + } + + // Check for duplicate parts + if ((mtd_image.filename) && (mtd_kernel.filename || mtd_rootfs.filename)) { + exitcode = 1; + printf("Image and kernel/rootfs specified in parameter file\n"); + } + lprintf(DEBUG, "...done checking mtd data\n"); } diff --git a/tools/xfce-macros/Makefile b/tools/xfce-macros/Makefile deleted file mode 100644 index 974404714dd..00000000000 --- a/tools/xfce-macros/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (C) 2011 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=xfce-macros -PKG_VERSION:=4.8.0 - -PKG_SOURCE_URL:=http://archive.xfce.org/xfce/4.8/src -PKG_SOURCE:=xfce4-dev-tools-$(PKG_VERSION).tar.bz2 -PKG_MD5SUM:=9591299c49d92d00ba47974c42a735fa - -HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/xfce4-dev-tools-$(PKG_VERSION) - -include $(INCLUDE_DIR)/host-build.mk - -define Host/Configure -endef - -define Host/Compile -endef - -define Host/Install - $(INSTALL_DIR) $(STAGING_DIR_HOST)/share/aclocal - $(INSTALL_DATA) $(HOST_BUILD_DIR)/m4macros/*.m4 $(STAGING_DIR_HOST)/share/aclocal/ -endef - -$(eval $(call HostBuild)) diff --git a/tools/xorg-macros/Makefile b/tools/xorg-macros/Makefile deleted file mode 100644 index 54df4028e93..00000000000 --- a/tools/xorg-macros/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (C) 2010 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=xorg-macros -PKG_VERSION:=1.11.0 - -PKG_SOURCE_URL:=http://xorg.freedesktop.org/releases/individual/util/ -PKG_SOURCE:=util-macros-$(PKG_VERSION).tar.bz2 -PKG_MD5SUM:=22d5cdff672450cb6902e0d68c200dcb - -HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/util-macros-$(PKG_VERSION) - -include $(INCLUDE_DIR)/host-build.mk - -define Host/Install - $(INSTALL_DIR) $(STAGING_DIR_HOST)/share/aclocal - $(INSTALL_DATA) $(HOST_BUILD_DIR)/xorg-macros.m4 $(STAGING_DIR_HOST)/share/aclocal/ -endef - -define Host/Clean - -$(MAKE) -C $(HOST_BUILD_DIR) uninstall - $(call Host/Clean/Default) -endef - -$(eval $(call HostBuild)) diff --git a/tools/xz/Makefile b/tools/xz/Makefile index cabc4fdfbb7..d6b619db41f 100644 --- a/tools/xz/Makefile +++ b/tools/xz/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006 OpenWrt.org +# Copyright (C) 2006-2015 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -7,16 +7,27 @@ include $(TOPDIR)/rules.mk PKG_NAME:=xz -PKG_VERSION:=5.0.2 +PKG_VERSION:=5.2.4 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 -PKG_SOURCE_URL:=http://tukaani.org/xz -PKG_MD5SUM:=ee05b17a4062bb55cba099ef46eca007 +PKG_SOURCE_URL:=@SF/lzmautils \ + http://tukaani.org/xz +PKG_HASH:=3313fd2a95f43d88e44264e6b015e7d03053e681860b0d5d3f9baca79c57b7bf + +HOST_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/host-build.mk +HOSTCC := $(HOSTCC_NOCACHE) +HOSTCXX := $(HOSTCXX_NOCACHE) + +HOST_CONFIGURE_ARGS += \ + --enable-static=yes \ + --enable-shared=no \ + --disable-doc + define Host/Install - $(MAKE) -C $(HOST_BUILD_DIR) install xzlinks="unxz xzcat" + +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR) install xzlinks="unxz xzcat" endef $(eval $(call HostBuild)) diff --git a/tools/yaffs2/Makefile b/tools/yaffs2/Makefile deleted file mode 100644 index 344b61a2c86..00000000000 --- a/tools/yaffs2/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (C) 2008 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=yaffs2_android -PKG_VERSION:=2008-12-18 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 -PKG_SOURCE_URL:=git://android.git.kernel.org/platform/external/yaffs2.git -PKG_SOURCE_PROTO:=git -PKG_SOURCE_SUBDIR:=$(PKG_NAME) -PKG_SOURCE_VERSION:=d333fc232d7e5ae3370080d5d6f7d88ea9c6b3a1 -HOST_BUILD_DIR=$(BUILD_DIR_HOST)/$(PKG_NAME) - -include $(INCLUDE_DIR)/host-build.mk - -define Host/Compile - $(MAKE) -C $(HOST_BUILD_DIR)/yaffs2/utils \ - CFLAGS="$(HOST_CFLAGS) -include endian.h" \ - mkyaffs2image -endef - -define Host/Install - $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin - $(INSTALL_BIN) $(HOST_BUILD_DIR)/yaffs2/utils/mkyaffs2image $(STAGING_DIR_HOST)/bin/ -endef - -define Host/Clean - rm -f $(STAGING_DIR_HOST)/bin/mkyaffs2image -endef - -$(eval $(call HostBuild)) diff --git a/tools/yaffs2/patches/100-compile.patch b/tools/yaffs2/patches/100-compile.patch deleted file mode 100644 index 2f83e1fff2d..00000000000 --- a/tools/yaffs2/patches/100-compile.patch +++ /dev/null @@ -1,125 +0,0 @@ ---- a/yaffs2/utils/Makefile -+++ b/yaffs2/utils/Makefile -@@ -16,12 +16,11 @@ - - #KERNELDIR = /usr/src/kernel-headers-2.4.18 - --CFLAGS = -I/usr/include -I.. -O2 -Wall -DCONFIG_YAFFS_UTIL --CFLAGS+= -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations --CFLAGS+= -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline -+CPPFLAGS = -I.. -DCONFIG_YAFFS_UTIL -+CFLAGS = -O2 - - ## Change if you are using a cross-compiler --MAKETOOLS = -+MAKETOOLS = - - CC=$(MAKETOOLS)gcc - -@@ -41,7 +40,7 @@ $(COMMONLINKS) $(MKYAFFSLINKS) $(MKYAFFS - ln -s ../$@ $@ - - $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) $(MKYAFFS2IMAGEOBJS) : %.o: %.c -- $(CC) -c $(CFLAGS) $< -o $@ -+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ - - mkyaffsimage: $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) - $(CC) -o $@ $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) ---- a/yaffs2/utils/mkyaffs2image.c -+++ b/yaffs2/utils/mkyaffs2image.c -@@ -32,8 +32,6 @@ - #include <string.h> - #include <unistd.h> - --#include <private/android_filesystem_config.h> -- - #include "yaffs_ecc.h" - #include "yaffs_guts.h" - -@@ -69,10 +67,12 @@ static int outFile; - - static int error; - --#ifdef HAVE_BIG_ENDIAN -+#if BYTE_ORDER == BIG_ENDIAN - static int convert_endian = 1; --#elif defined(HAVE_LITTLE_ENDIAN) -+#elif BYTE_ORDER == LITTLE_ENDIAN - static int convert_endian = 0; -+#else -+#error Unknown endian type - #endif - - static int obj_compare(const void *a, const void * b) -@@ -298,8 +298,8 @@ static int write_object_header(int objId - - static void fix_stat(const char *path, struct stat *s) - { -- path += source_path_len; -- fs_config(path, S_ISDIR(s->st_mode), &s->st_uid, &s->st_gid, &s->st_mode); -+ s->st_uid = 0; -+ s->st_gid = 0; - } - - static int process_directory(int parent, const char *path, int fixstats) -@@ -342,9 +342,8 @@ static int process_directory(int parent, - newObj = obj_id++; - nObjects++; - -- if (fixstats) { -+ if (fixstats) - fix_stat(full_name, &stats); -- } - - //printf("Object %d, %s is a ",newObj,full_name); - -@@ -473,13 +472,13 @@ int main(int argc, char *argv[]) - fprintf(stderr," -f fix file stat (mods, user, group) for device\n"); - fprintf(stderr," dir the directory tree to be converted\n"); - fprintf(stderr," image_file the output file to hold the image\n"); -- fprintf(stderr," 'convert' produce a big-endian image from a little-endian machine\n"); -+ fprintf(stderr," 'convert' produce a big-endian image\n"); - exit(1); - } - - if ((argc == 4) && (!strncmp(argv[3], "convert", strlen("convert")))) - { -- convert_endian = 1; -+ convert_endian = !convert_endian; - } - - if(stat(argv[1],&stats) < 0) -@@ -503,20 +502,9 @@ int main(int argc, char *argv[]) - exit(1); - } - -- if (fixstats) { -- int len = strlen(argv[1]); -- -- if((len >= 4) && (!strcmp(argv[1] + len - 4, "data"))) { -- source_path_len = len - 4; -- } else if((len >= 7) && (!strcmp(argv[1] + len - 6, "system"))) { -- source_path_len = len - 6; -- } else { -- fprintf(stderr,"Fixstats (-f) option requested but filesystem is not data or android!\n"); -- exit(1); -- } -+ if (fixstats) - fix_stat(argv[1], &stats); -- } -- -+ - //printf("Processing directory %s into image file %s\n",argv[1],argv[2]); - error = write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL); - if(error) ---- a/yaffs2/devextras.h -+++ b/yaffs2/devextras.h -@@ -37,7 +37,7 @@ typedef unsigned char __u8; - typedef unsigned short __u16; - typedef unsigned __u32; - --#if defined(__APPLE__) -+#if defined(__APPLE__) || defined(__FreeBSD__) - typedef long long loff_t; - #endif - diff --git a/tools/zlib/Makefile b/tools/zlib/Makefile new file mode 100644 index 00000000000..279851f758d --- /dev/null +++ b/tools/zlib/Makefile @@ -0,0 +1,41 @@ +# +# Copyright (C) 2006-2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=zlib +PKG_VERSION:=1.2.11 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=@SF/libpng http://www.zlib.net +PKG_HASH:=4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066 + +PKG_LICENSE:=Zlib +PKG_LICENSE_FILES:=README +PKG_CPE_ID:=cpe:/a:gnu:zlib + +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/cmake.mk + +HOST_CFLAGS +=-fPIC + +define Host/Install + $(CP) $(HOST_BUILD_DIR)/libz.a $(STAGING_DIR_HOST)/lib/ + $(CP) $(HOST_BUILD_DIR)/zconf.h $(STAGING_DIR_HOST)/include/ + $(CP) $(HOST_BUILD_DIR)/zlib.h $(STAGING_DIR_HOST)/include/ + $(CP) $(HOST_BUILD_DIR)/zlib.pc $(STAGING_DIR_HOST)/lib/pkgconfig/ +endef + +define Host/Clean + rm -f $(STAGING_DIR_HOST)/lib/libz.a + rm -f $(STAGING_DIR_HOST)/include/zconf.h + rm -f $(STAGING_DIR_HOST)/include/zlib.h + rm -f $(STAGING_DIR_HOST)/lib/pkgconfig//zlib.pc +endef + +$(eval $(call HostBuild)) diff --git a/tools/zlib/patches/900-overridable-pc-exec-prefix.patch b/tools/zlib/patches/900-overridable-pc-exec-prefix.patch new file mode 100644 index 00000000000..4f1e376c909 --- /dev/null +++ b/tools/zlib/patches/900-overridable-pc-exec-prefix.patch @@ -0,0 +1,14 @@ +--- a/zlib.pc.cmakein ++++ b/zlib.pc.cmakein +@@ -1,8 +1,8 @@ + prefix=@CMAKE_INSTALL_PREFIX@ + exec_prefix=@CMAKE_INSTALL_PREFIX@ +-libdir=@INSTALL_LIB_DIR@ +-sharedlibdir=@INSTALL_LIB_DIR@ +-includedir=@INSTALL_INC_DIR@ ++libdir=${prefix}/lib ++sharedlibdir=${prefix}/lib ++includedir=${prefix}/include + + Name: zlib + Description: zlib compression library |
