diff options
Diffstat (limited to 'build')
-rw-r--r-- | build/arm-msvs/obj_int_extract.bat | 14 | ||||
-rw-r--r-- | build/make/Android.mk | 45 | ||||
-rw-r--r-- | build/make/Makefile | 44 | ||||
-rwxr-xr-x | build/make/ads2armasm_ms.pl | 38 | ||||
-rwxr-xr-x | build/make/ads2gas.pl | 28 | ||||
-rwxr-xr-x | build/make/ads2gas_apple.pl | 29 | ||||
-rwxr-xr-x | build/make/armlink_adapter.sh | 14 | ||||
-rwxr-xr-x | build/make/configure.sh | 264 | ||||
-rwxr-xr-x | build/make/gen_asm_deps.sh | 2 | ||||
-rwxr-xr-x | build/make/gen_msvs_proj.sh | 55 | ||||
-rwxr-xr-x | build/make/gen_msvs_sln.sh | 89 | ||||
-rwxr-xr-x | build/make/gen_msvs_vcxproj.sh | 544 | ||||
-rw-r--r-- | build/make/obj_int_extract.c | 1461 | ||||
-rwxr-xr-x | build/make/rtcd.sh | 69 | ||||
-rw-r--r-- | build/make/thumb.pm | 70 | ||||
-rwxr-xr-x | build/make/version.sh | 2 | ||||
-rw-r--r-- | build/x86-msvs/obj_int_extract.bat | 9 | ||||
-rw-r--r-- | build/x86-msvs/yasm.rules | 115 |
18 files changed, 1792 insertions, 1100 deletions
diff --git a/build/arm-msvs/obj_int_extract.bat b/build/arm-msvs/obj_int_extract.bat new file mode 100644 index 000000000..7fd16a303 --- /dev/null +++ b/build/arm-msvs/obj_int_extract.bat @@ -0,0 +1,14 @@ +REM Copyright (c) 2013 The WebM project authors. All Rights Reserved. +REM +REM Use of this source code is governed by a BSD-style license +REM that can be found in the LICENSE file in the root of the source +REM tree. An additional intellectual property rights grant can be found +REM in the file PATENTS. All contributing project authors may +REM be found in the AUTHORS file in the root of the source tree. +echo on + +cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vp8/encoder/vp8_asm_enc_offsets.c" +obj_int_extract.exe rvds "vp8_asm_enc_offsets.obj" > "vp8_asm_enc_offsets.asm" + +cl /I "./" /I "%1" /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%1/vpx_scale/vpx_scale_asm_offsets.c" +obj_int_extract.exe rvds "vpx_scale_asm_offsets.obj" > "vpx_scale_asm_offsets.asm" diff --git a/build/make/Android.mk b/build/make/Android.mk index c6b9cf936..1ff0884fc 100644 --- a/build/make/Android.mk +++ b/build/make/Android.mk @@ -48,7 +48,7 @@ # Running ndk-build will build libvpx and include it in your project. # -CONFIG_DIR := $(LOCAL_PATH) +CONFIG_DIR := $(LOCAL_PATH)/ LIBVPX_PATH := $(LOCAL_PATH)/libvpx ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas ASM_CNV_PATH := $(LOCAL_PATH)/$(ASM_CNV_PATH_LOCAL) @@ -56,9 +56,9 @@ ASM_CNV_PATH := $(LOCAL_PATH)/$(ASM_CNV_PATH_LOCAL) # Makefiles created by the libvpx configure process # This will need to be fixed to handle x86. ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) - include $(CONFIG_DIR)/libs-armv7-android-gcc.mk + include $(CONFIG_DIR)libs-armv7-android-gcc.mk else - include $(CONFIG_DIR)/libs-armv5te-android-gcc.mk + include $(CONFIG_DIR)libs-armv5te-android-gcc.mk endif # Rule that is normally in Makefile created by libvpx @@ -106,26 +106,25 @@ $$(eval $$(call ev-build-file)) $(1) : $$(_OBJ) $(2) @mkdir -p $$(dir $$@) - @grep $(OFFSET_PATTERN) $$< | tr -d '\#' | $(CONFIG_DIR)/$(ASM_CONVERSION) > $$@ + @grep $(OFFSET_PATTERN) $$< | tr -d '\#' | $(CONFIG_DIR)$(ASM_CONVERSION) > $$@ endef # Use ads2gas script to convert from RVCT format to GAS format. This passes # puts the processed file under $(ASM_CNV_PATH). Local clean rule # to handle removing these -ASM_CNV_OFFSETS_DEPEND = $(ASM_CNV_PATH)/asm_com_offsets.asm -ifeq ($(CONFIG_VP8_DECODER), yes) - ASM_CNV_OFFSETS_DEPEND += $(ASM_CNV_PATH)/asm_dec_offsets.asm -endif ifeq ($(CONFIG_VP8_ENCODER), yes) - ASM_CNV_OFFSETS_DEPEND += $(ASM_CNV_PATH)/asm_enc_offsets.asm + ASM_CNV_OFFSETS_DEPEND += $(ASM_CNV_PATH)/vp8_asm_enc_offsets.asm +endif +ifeq ($(HAVE_NEON), yes) + ASM_CNV_OFFSETS_DEPEND += $(ASM_CNV_PATH)/vpx_scale_asm_offsets.asm endif .PRECIOUS: %.asm.s $(ASM_CNV_PATH)/libvpx/%.asm.s: $(LIBVPX_PATH)/%.asm $(ASM_CNV_OFFSETS_DEPEND) @mkdir -p $(dir $@) - @$(CONFIG_DIR)/$(ASM_CONVERSION) <$< > $@ + @$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@ -# For building vpx_rtcd.h, which has a rule in libs.mk +# For building *_rtcd.h, which have rules in libs.mk TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN))) target := libs @@ -177,7 +176,14 @@ ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes) LOCAL_STATIC_LIBRARIES := cpufeatures endif -$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vpx_rtcd.h +# Add a dependency to force generation of the RTCD files. +ifeq ($(CONFIG_VP8), yes) +$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vp8_rtcd.h +endif +ifeq ($(CONFIG_VP9), yes) +$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vp9_rtcd.h +endif +$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vpx_scale_rtcd.h .PHONY: clean clean: @@ -189,23 +195,18 @@ clean: include $(BUILD_SHARED_LIBRARY) -$(eval $(call asm_offsets_template,\ - $(ASM_CNV_PATH)/asm_com_offsets.asm, \ - $(LIBVPX_PATH)/vp8/common/asm_com_offsets.c)) - -ifeq ($(CONFIG_VP8_DECODER), yes) +ifeq ($(HAVE_NEON), yes) $(eval $(call asm_offsets_template,\ - $(ASM_CNV_PATH)/asm_dec_offsets.asm, \ - $(LIBVPX_PATH)/vp8/decoder/asm_dec_offsets.c)) + $(ASM_CNV_PATH)/vpx_scale_asm_offsets.asm, \ + $(LIBVPX_PATH)/vpx_scale/vpx_scale_asm_offsets.c)) endif ifeq ($(CONFIG_VP8_ENCODER), yes) $(eval $(call asm_offsets_template,\ - $(ASM_CNV_PATH)/asm_enc_offsets.asm, \ - $(LIBVPX_PATH)/vp8/encoder/asm_enc_offsets.c)) + $(ASM_CNV_PATH)/vp8_asm_enc_offsets.asm, \ + $(LIBVPX_PATH)/vp8/encoder/vp8_asm_enc_offsets.c)) endif ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes) $(call import-module,cpufeatures) endif - diff --git a/build/make/Makefile b/build/make/Makefile index 1088c841a..030c1b57f 100644 --- a/build/make/Makefile +++ b/build/make/Makefile @@ -74,7 +74,7 @@ HOSTCC?=gcc TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN))) TGT_OS:=$(word 2, $(subst -, ,$(TOOLCHAIN))) TGT_CC:=$(word 3, $(subst -, ,$(TOOLCHAIN))) -quiet:=$(if $(verbose),,yes) +quiet:=$(if $(or $(verbose), $(V)),, yes) qexec=$(if $(quiet),@) # Cancel built-in implicit rules @@ -103,6 +103,22 @@ test:: .PHONY: testdata testdata:: +# Add compiler flags for intrinsic files +$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx +$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx +$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2 +$(BUILD_PFX)%_sse2.c.o: CFLAGS += -msse2 +$(BUILD_PFX)%_sse3.c.d: CFLAGS += -msse3 +$(BUILD_PFX)%_sse3.c.o: CFLAGS += -msse3 +$(BUILD_PFX)%_ssse3.c.d: CFLAGS += -mssse3 +$(BUILD_PFX)%_ssse3.c.o: CFLAGS += -mssse3 +$(BUILD_PFX)%_sse4.c.d: CFLAGS += -msse4.1 +$(BUILD_PFX)%_sse4.c.o: CFLAGS += -msse4.1 +$(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx +$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx +$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2 +$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2 + $(BUILD_PFX)%.c.d: %.c $(if $(quiet),@echo " [DEP] $@") $(qexec)mkdir -p $(dir $@) @@ -253,10 +269,25 @@ $(1): $(if $(quiet),@echo " [LD] $$@") $(qexec)$$(LD) -shared $$(LDFLAGS) \ -Wl,--no-undefined -Wl,-soname,$$(SONAME) \ - -Wl,--version-script,$$(SO_VERSION_SCRIPT) -o $$@ \ - $$(filter %.o,$$?) $$(extralibs) + -Wl,--version-script,$$(EXPORTS_FILE) -o $$@ \ + $$(filter %.o,$$^) $$(extralibs) +endef + +define dl_template +# Not using a pattern rule here because we don't want to generate empty +# archives when they are listed as a dependency in files not responsible +# for creating them. +$(1): + $(if $(quiet),@echo " [LD] $$@") + $(qexec)$$(LD) -dynamiclib $$(LDFLAGS) \ + -exported_symbols_list $$(EXPORTS_FILE) \ + -Wl,-headerpad_max_install_names,-compatibility_version,1.0,-current_version,$$(VERSION_MAJOR) \ + -o $$@ \ + $$(filter %.o,$$^) $$(extralibs) endef + + define lipo_lib_template $(1): $(addsuffix /$(1),$(FAT_ARCHS)) $(if $(quiet),@echo " [LIPO] $$@") @@ -321,6 +352,7 @@ LIBS=$(call enabled,LIBS) @touch $@ $(foreach lib,$(filter %_g.a,$(LIBS)),$(eval $(call archive_template,$(lib)))) $(foreach lib,$(filter %so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH),$(LIBS)),$(eval $(call so_template,$(lib)))) +$(foreach lib,$(filter %$(VERSION_MAJOR).dylib,$(LIBS)),$(eval $(call dl_template,$(lib)))) INSTALL-LIBS=$(call cond_enabled,CONFIG_INSTALL_LIBS,INSTALL-LIBS) ifeq ($(MAKECMDGOALS),dist) @@ -360,10 +392,14 @@ ifneq ($(call enabled,DIST-SRCS),) DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_sln.sh DIST-SRCS-$(CONFIG_MSVS) += build/x86-msvs/yasm.rules DIST-SRCS-$(CONFIG_MSVS) += build/x86-msvs/obj_int_extract.bat + DIST-SRCS-$(CONFIG_MSVS) += build/arm-msvs/obj_int_extract.bat DIST-SRCS-$(CONFIG_RVCT) += build/make/armlink_adapter.sh - # Include obj_int_extract if we use offsets from asm_*_offsets + # Include obj_int_extract if we use offsets from *_asm_*_offsets DIST-SRCS-$(ARCH_ARM)$(ARCH_X86)$(ARCH_X86_64) += build/make/obj_int_extract.c DIST-SRCS-$(ARCH_ARM) += build/make/ads2gas.pl + DIST-SRCS-$(ARCH_ARM) += build/make/ads2gas_apple.pl + DIST-SRCS-$(ARCH_ARM) += build/make/ads2armasm_ms.pl + DIST-SRCS-$(ARCH_ARM) += build/make/thumb.pm DIST-SRCS-yes += $(target:-$(TOOLCHAIN)=).mk endif INSTALL-SRCS := $(call cond_enabled,CONFIG_INSTALL_SRCS,INSTALL-SRCS) diff --git a/build/make/ads2armasm_ms.pl b/build/make/ads2armasm_ms.pl new file mode 100755 index 000000000..1def53901 --- /dev/null +++ b/build/make/ads2armasm_ms.pl @@ -0,0 +1,38 @@ +#!/usr/bin/perl +## +## Copyright (c) 2013 The WebM project authors. All Rights Reserved. +## +## Use of this source code is governed by a BSD-style license +## that can be found in the LICENSE file in the root of the source +## tree. An additional intellectual property rights grant can be found +## in the file PATENTS. All contributing project authors may +## be found in the AUTHORS file in the root of the source tree. +## + +use FindBin; +use lib $FindBin::Bin; +use thumb; + +print "; This file was created from a .asm file\n"; +print "; using the ads2armasm_ms.pl script.\n"; + +while (<STDIN>) +{ + undef $comment; + undef $line; + + s/REQUIRE8//; + s/PRESERVE8//; + s/^\s*ARM\s*$//; + s/AREA\s+\|\|(.*)\|\|/AREA |$1|/; + s/qsubaddx/qsax/i; + s/qaddsubx/qasx/i; + + thumb::FixThumbInstructions($_, 1); + + s/ldrneb/ldrbne/i; + s/ldrneh/ldrhne/i; + + print; +} + diff --git a/build/make/ads2gas.pl b/build/make/ads2gas.pl index 95be467ab..9c4190129 100755 --- a/build/make/ads2gas.pl +++ b/build/make/ads2gas.pl @@ -17,9 +17,24 @@ # # Usage: cat inputfile | perl ads2gas.pl > outputfile # + +use FindBin; +use lib $FindBin::Bin; +use thumb; + +my $thumb = 0; + +foreach my $arg (@ARGV) { + $thumb = 1 if ($arg eq "-thumb"); +} + print "@ This file was created from a .asm file\n"; print "@ using the ads2gas.pl script.\n"; print "\t.equ DO1STROUNDING, 0\n"; +if ($thumb) { + print "\t.syntax unified\n"; + print "\t.thumb\n"; +} # Stack of procedure names. @proc_stack = (); @@ -151,8 +166,13 @@ while (<STDIN>) # ALIGN directive s/\bALIGN\b/.balign/g; - # ARM code - s/\sARM/.arm/g; + if ($thumb) { + # ARM code - we force everything to thumb with the declaration in the header + s/\sARM//g; + } else { + # ARM code + s/\sARM/.arm/g; + } # push/pop s/(push\s+)(r\d+)/stmdb sp\!, \{$2\}/g; @@ -162,6 +182,10 @@ while (<STDIN>) s/(vld1.\d+\s+)(q\d+)/$1\{$2\}/g; s/(vtbl.\d+\s+[^,]+),([^,]+)/$1,\{$2\}/g; + if ($thumb) { + thumb::FixThumbInstructions($_, 0); + } + # eabi_attributes numerical equivalents can be found in the # "ARM IHI 0045C" document. diff --git a/build/make/ads2gas_apple.pl b/build/make/ads2gas_apple.pl index 81280bf78..befb3dbe7 100755 --- a/build/make/ads2gas_apple.pl +++ b/build/make/ads2gas_apple.pl @@ -10,13 +10,20 @@ ## -# ads2gas.pl +# ads2gas_apple.pl # Author: Eric Fung (efung (at) acm.org) # # Convert ARM Developer Suite 1.0.1 syntax assembly source to GNU as format # -# Usage: cat inputfile | perl ads2gas.pl > outputfile +# Usage: cat inputfile | perl ads2gas_apple.pl > outputfile # + +my $chromium = 0; + +foreach my $arg (@ARGV) { + $chromium = 1 if ($arg eq "-chromium"); +} + print "@ This file was created from a .asm file\n"; print "@ using the ads2gas_apple.pl script.\n\n"; print "\t.set WIDE_REFERENCE, 0\n"; @@ -47,7 +54,7 @@ while (<STDIN>) s/@/,:/g; # Comment character - s/;/@/g; + s/;/ @/g; # Hexadecimal constants prefaced by 0x s/#&/#0x/g; @@ -188,7 +195,7 @@ while (<STDIN>) $trimmed =~ s/,//g; # string to array - @incoming_array = split(/ /, $trimmed); + @incoming_array = split(/\s+/, $trimmed); print ".macro @incoming_array[0]\n"; @@ -210,5 +217,19 @@ while (<STDIN>) # s/\$/\\/g; # End macro definition s/MEND/.endm/; # No need to tell it where to stop assembling next if /^\s*END\s*$/; + + # Clang used by Chromium differs slightly from clang in XCode in what it + # will accept in the assembly. + if ($chromium) { + s/qsubaddx/qsax/i; + s/qaddsubx/qasx/i; + s/ldrneb/ldrbne/i; + s/ldrneh/ldrhne/i; + s/(vqshrun\.s16 .*, \#)0$/${1}8/i; + + # http://llvm.org/bugs/show_bug.cgi?id=16022 + s/\.include/#include/; + } + print; } diff --git a/build/make/armlink_adapter.sh b/build/make/armlink_adapter.sh index b53669c9b..75c342e97 100755 --- a/build/make/armlink_adapter.sh +++ b/build/make/armlink_adapter.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh ## ## Copyright (c) 2010 The WebM project authors. All Rights Reserved. ## @@ -13,20 +13,20 @@ verbose=0 set -- $* for i; do - if [ "$i" == "-o" ]; then + if [ "$i" = "-o" ]; then on_of=1 - elif [ "$i" == "-v" ]; then + elif [ "$i" = "-v" ]; then verbose=1 - elif [ "$i" == "-g" ]; then + elif [ "$i" = "-g" ]; then args="${args} --debug" - elif [ "$on_of" == "1" ]; then + elif [ "$on_of" = "1" ]; then outfile=$i on_of=0 elif [ -f "$i" ]; then infiles="$infiles $i" - elif [ "${i:0:2}" == "-l" ]; then + elif [ "${i#-l}" != "$i" ]; then libs="$libs ${i#-l}" - elif [ "${i:0:2}" == "-L" ]; then + elif [ "${i#-L}" != "$i" ]; then libpaths="${libpaths} ${i#-L}" else args="${args} ${i}" diff --git a/build/make/configure.sh b/build/make/configure.sh index c99a01cd9..8dcb9bbf4 100755 --- a/build/make/configure.sh +++ b/build/make/configure.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh ## ## configure.sh ## @@ -75,7 +75,7 @@ Options: Build options: --help print this message - --log=yes|no|FILE file configure log is written to [config.err] + --log=yes|no|FILE file configure log is written to [config.log] --target=TARGET target platform tuple [generic-gnu] --cpu=CPU optimize for a specific cpu rather than a family --extra-cflags=ECFLAGS add ECFLAGS to CFLAGS [$CFLAGS] @@ -88,6 +88,7 @@ Build options: ${toggle_debug} enable/disable debug mode ${toggle_gprof} enable/disable gprof profiling instrumentation ${toggle_gcov} enable/disable gcov coverage instrumentation + ${toggle_thumb} enable/disable building arm assembly in thumb mode Install options: ${toggle_install_docs} control whether docs are installed @@ -197,11 +198,11 @@ add_extralibs() { # # Boolean Manipulation Functions # -enable(){ +enable_feature(){ set_all yes $* } -disable(){ +disable_feature(){ set_all no $* } @@ -218,7 +219,7 @@ soft_enable() { for var in $*; do if ! disabled $var; then log_echo " enabling $var" - enable $var + enable_feature $var fi done } @@ -227,7 +228,7 @@ soft_disable() { for var in $*; do if ! enabled $var; then log_echo " disabling $var" - disable $var + disable_feature $var fi done } @@ -250,10 +251,10 @@ tolower(){ # Temporary File Functions # source_path=${0%/*} -enable source_path_used +enable_feature source_path_used if test -z "$source_path" -o "$source_path" = "." ; then source_path="`pwd`" - disable source_path_used + disable_feature source_path_used fi if test ! -z "$TMPDIR" ; then @@ -263,20 +264,23 @@ elif test ! -z "$TEMPDIR" ; then else TMPDIRx="/tmp" fi -TMP_H="${TMPDIRx}/vpx-conf-$$-${RANDOM}.h" -TMP_C="${TMPDIRx}/vpx-conf-$$-${RANDOM}.c" -TMP_O="${TMPDIRx}/vpx-conf-$$-${RANDOM}.o" -TMP_X="${TMPDIRx}/vpx-conf-$$-${RANDOM}.x" -TMP_ASM="${TMPDIRx}/vpx-conf-$$-${RANDOM}.asm" +RAND=$(awk 'BEGIN { srand(); printf "%d\n",(rand() * 32768)}') +TMP_H="${TMPDIRx}/vpx-conf-$$-${RAND}.h" +TMP_C="${TMPDIRx}/vpx-conf-$$-${RAND}.c" +TMP_CC="${TMPDIRx}/vpx-conf-$$-${RAND}.cc" +TMP_O="${TMPDIRx}/vpx-conf-$$-${RAND}.o" +TMP_X="${TMPDIRx}/vpx-conf-$$-${RAND}.x" +TMP_ASM="${TMPDIRx}/vpx-conf-$$-${RAND}.asm" clean_temp_files() { - rm -f ${TMP_C} ${TMP_H} ${TMP_O} ${TMP_X} ${TMP_ASM} + rm -f ${TMP_C} ${TMP_CC} ${TMP_H} ${TMP_O} ${TMP_X} ${TMP_ASM} } # # Toolchain Check Functions # check_cmd() { + enabled external_build && return log "$@" "$@" >>${logfile} 2>&1 } @@ -290,9 +294,9 @@ check_cc() { check_cxx() { log check_cxx "$@" - cat >${TMP_C} - log_file ${TMP_C} - check_cmd ${CXX} ${CXXFLAGS} "$@" -c -o ${TMP_O} ${TMP_C} + cat >${TMP_CC} + log_file ${TMP_CC} + check_cmd ${CXX} ${CXXFLAGS} "$@" -c -o ${TMP_O} ${TMP_CC} } check_cpp() { @@ -313,8 +317,8 @@ check_header(){ header=$1 shift var=`echo $header | sed 's/[^A-Za-z0-9_]/_/g'` - disable $var - check_cpp "$@" <<EOF && enable $var + disable_feature $var + check_cpp "$@" <<EOF && enable_feature $var #include "$header" int x; EOF @@ -414,6 +418,8 @@ SRC_PATH_BARE=$source_path BUILD_PFX=${BUILD_PFX} TOOLCHAIN=${toolchain} ASM_CONVERSION=${asm_conversion_cmd:-${source_path}/build/make/ads2gas.pl} +GEN_VCPROJ=${gen_vcproj_cmd} +MSVS_ARCH_DIR=${msvs_arch_dir} CC=${CC} CXX=${CXX} @@ -431,14 +437,15 @@ ASFLAGS = ${ASFLAGS} extralibs = ${extralibs} AS_SFX = ${AS_SFX:-.asm} EXE_SFX = ${EXE_SFX} +VCPROJ_SFX = ${VCPROJ_SFX} RTCD_OPTIONS = ${RTCD_OPTIONS} EOF if enabled rvct; then cat >> $1 << EOF -fmt_deps = sed -e 's;^__image.axf;\$(dir \$@)\$(notdir \$<).o \$@;' #hide +fmt_deps = sed -e 's;^__image.axf;\${@:.d=.o} \$@;' #hide EOF else cat >> $1 << EOF -fmt_deps = sed -e 's;^\([a-zA-Z0-9_]*\)\.o;\$(dir \$@)\1\$(suffix \$<).o \$@;' +fmt_deps = sed -e 's;^\([a-zA-Z0-9_]*\)\.o;\${@:.d=.o} \$@;' EOF fi @@ -459,6 +466,7 @@ write_common_target_config_h() { #ifndef VPX_CONFIG_H #define VPX_CONFIG_H #define RESTRICT ${RESTRICT} +#define INLINE ${INLINE} EOF print_config_h ARCH "${TMP_H}" ${ARCH_LIST} print_config_h HAVE "${TMP_H}" ${HAVE_LIST} @@ -472,7 +480,7 @@ process_common_cmdline() { for opt in "$@"; do optval="${opt#*=}" case "$opt" in - --child) enable child + --child) enable_feature child ;; --log*) logging="$optval" @@ -484,7 +492,7 @@ process_common_cmdline() { ;; --target=*) toolchain="${toolchain:-${optval}}" ;; - --force-target=*) toolchain="${toolchain:-${optval}}"; enable force_toolchain + --force-target=*) toolchain="${toolchain:-${optval}}"; enable_feature force_toolchain ;; --cpu) ;; @@ -504,7 +512,7 @@ process_common_cmdline() { echo "${CMDLINE_SELECT}" | grep "^ *$option\$" >/dev/null || die_unknown $opt fi - $action $option + ${action}_feature $option ;; --require-?*) eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'` @@ -516,11 +524,11 @@ process_common_cmdline() { ;; --force-enable-?*|--force-disable-?*) eval `echo "$opt" | sed 's/--force-/action=/;s/-/ option=/;s/-/_/g'` - $action $option + ${action}_feature $option ;; --libc=*) [ -d "${optval}" ] || die "Not a directory: ${optval}" - disable builtin_libc + disable_feature builtin_libc alt_libc="${optval}" ;; --as=*) @@ -596,8 +604,13 @@ process_common_toolchain() { armv6*) tgt_isa=armv6 ;; + armv7*-hardfloat*) + tgt_isa=armv7 + float_abi=hard + ;; armv7*) tgt_isa=armv7 + float_abi=softfp ;; armv5te*) tgt_isa=armv5te @@ -641,6 +654,13 @@ process_common_toolchain() { tgt_isa=x86_64 tgt_os=darwin12 ;; + *darwin13*) + tgt_isa=x86_64 + tgt_os=darwin13 + ;; + x86_64*mingw32*) + tgt_os=win64 + ;; *mingw32*|*cygwin*) [ -z "$tgt_isa" ] && tgt_isa=x86 tgt_os=win32 @@ -677,13 +697,13 @@ process_common_toolchain() { # Mark the specific ISA requested as enabled soft_enable ${tgt_isa} - enable ${tgt_os} - enable ${tgt_cc} + enable_feature ${tgt_os} + enable_feature ${tgt_cc} # Enable the architecture family case ${tgt_isa} in - arm*) enable arm;; - mips*) enable mips;; + arm*) enable_feature arm;; + mips*) enable_feature mips;; esac # PIC is probably what we want when building shared libs @@ -736,13 +756,17 @@ process_common_toolchain() { add_cflags "-mmacosx-version-min=10.8" add_ldflags "-mmacosx-version-min=10.8" ;; + *-darwin13-*) + add_cflags "-mmacosx-version-min=10.9" + add_ldflags "-mmacosx-version-min=10.9" + ;; esac # Handle Solaris variants. Solaris 10 needs -lposix4 case ${toolchain} in sparc-solaris-*) add_extralibs -lposix4 - disable fast_unaligned + disable_feature fast_unaligned ;; *-solaris-*) add_extralibs -lposix4 @@ -767,7 +791,7 @@ process_common_toolchain() { ;; armv5te) soft_enable edsp - disable fast_unaligned + disable_feature fast_unaligned ;; esac @@ -782,9 +806,16 @@ process_common_toolchain() { arch_int=${arch_int%%te} check_add_asflags --defsym ARCHITECTURE=${arch_int} tune_cflags="-mtune=" - if [ ${tgt_isa} == "armv7" ]; then - check_add_cflags -march=armv7-a -mfloat-abi=softfp - check_add_asflags -march=armv7-a -mfloat-abi=softfp + if [ ${tgt_isa} = "armv7" ]; then + if [ -z "${float_abi}" ]; then + check_cpp <<EOF && float_abi=hard || float_abi=softfp +#ifndef __ARM_PCS_VFP +#error "not hardfp" +#endif +EOF + fi + check_add_cflags -march=armv7-a -mfloat-abi=${float_abi} + check_add_asflags -march=armv7-a -mfloat-abi=${float_abi} if enabled neon then @@ -802,6 +833,18 @@ process_common_toolchain() { enabled debug && add_asflags -g asm_conversion_cmd="${source_path}/build/make/ads2gas.pl" + if enabled thumb; then + asm_conversion_cmd="$asm_conversion_cmd -thumb" + check_add_cflags -mthumb + check_add_asflags -mthumb -mimplicit-it=always + fi + ;; + vs*) + asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl" + AS_SFX=.s + msvs_arch_dir=arm-msvs + disable_feature multithread + disable_feature unit_tests ;; rvct) CC=armcc @@ -813,7 +856,7 @@ process_common_toolchain() { tune_cflags="--cpu=" tune_asflags="--cpu=" if [ -z "${tune_cpu}" ]; then - if [ ${tgt_isa} == "armv7" ]; then + if [ ${tgt_isa} = "armv7" ]; then if enabled neon then check_add_cflags --fpu=softvfp+vfpv3 @@ -838,8 +881,8 @@ process_common_toolchain() { case ${tgt_os} in none*) - disable multithread - disable os_support + disable_feature multithread + disable_feature os_support ;; android*) @@ -871,9 +914,9 @@ process_common_toolchain() { # Cortex-A8 implementations (NDK Dev Guide) add_ldflags "-Wl,--fix-cortex-a8" - enable pic + enable_feature pic soft_enable realtime_only - if [ ${tgt_isa} == "armv7" ]; then + if [ ${tgt_isa} = "armv7" ]; then soft_enable runtime_cpu_detect fi if enabled runtime_cpu_detect; then @@ -882,41 +925,26 @@ process_common_toolchain() { ;; darwin*) - if [ -z "${sdk_path}" ]; then - SDK_PATH=`xcode-select -print-path 2> /dev/null` - SDK_PATH=${SDK_PATH}/Platforms/iPhoneOS.platform/Developer - else - SDK_PATH=${sdk_path} - fi - TOOLCHAIN_PATH=${SDK_PATH}/usr/bin - CXX=${TOOLCHAIN_PATH}/g++ - CC=${TOOLCHAIN_PATH}/gcc - AR=${TOOLCHAIN_PATH}/ar - LD=${TOOLCHAIN_PATH}/arm-apple-darwin10-llvm-gcc-4.2 - AS=${TOOLCHAIN_PATH}/as - STRIP=${TOOLCHAIN_PATH}/strip - NM=${TOOLCHAIN_PATH}/nm + + XCRUN_FIND="xcrun --sdk iphoneos -find" + CXX="$(${XCRUN_FIND} clang++)" + CC="$(${XCRUN_FIND} clang)" + AR="$(${XCRUN_FIND} ar)" + LD="$(${XCRUN_FIND} ld)" + AS="$(${XCRUN_FIND} as)" + STRIP="$(${XCRUN_FIND} strip)" + NM="$(${XCRUN_FIND} nm)" + RANLIB="$(${XCRUN_FIND} ranlib)" AS_SFX=.s # ASFLAGS is written here instead of using check_add_asflags # because we need to overwrite all of ASFLAGS and purge the # options that were put in above - ASFLAGS="-version -arch ${tgt_isa} -g" - - add_cflags -arch ${tgt_isa} - add_ldflags -arch_only ${tgt_isa} - - if [ -z "${alt_libc}" ]; then - alt_libc=${SDK_PATH}/SDKs/iPhoneOS5.1.sdk - fi - - add_cflags "-isysroot ${alt_libc}" + ASFLAGS="-arch ${tgt_isa} -g" - # Add the paths for the alternate libc - for d in usr/include; do - try_dir="${alt_libc}/${d}" - [ -d "${try_dir}" ] && add_cflags -I"${try_dir}" - done + alt_libc="$(xcrun --sdk iphoneos --show-sdk-path)" + add_cflags -arch ${tgt_isa} -isysroot ${alt_libc} + add_ldflags -arch ${tgt_isa} -ios_version_min 7.0 for d in lib usr/lib usr/lib/system; do try_dir="${alt_libc}/${d}" @@ -927,7 +955,7 @@ process_common_toolchain() { ;; linux*) - enable linux + enable_feature linux if enabled rvct; then # Check if we have CodeSourcery GCC in PATH. Needed for # libraries @@ -958,14 +986,14 @@ process_common_toolchain() { tune_cflags="-mtune=" if enabled dspr2; then check_add_cflags -mips32r2 -mdspr2 - disable fast_unaligned + disable_feature fast_unaligned fi check_add_cflags -march=${tgt_isa} check_add_asflags -march=${tgt_isa} check_add_asflags -KPIC ;; ppc*) - enable ppc + enable_feature ppc bits=${tgt_isa##ppc} link_with_cc=gcc setup_gnu_toolchain @@ -995,13 +1023,6 @@ process_common_toolchain() { #error "not x32" #endif EOF - soft_enable runtime_cpu_detect - soft_enable mmx - soft_enable sse - soft_enable sse2 - soft_enable sse3 - soft_enable ssse3 - soft_enable sse4_1 case ${tgt_os} in win*) @@ -1024,9 +1045,11 @@ EOF CC=${CC:-icc} LD=${LD:-icc} setup_gnu_toolchain - add_cflags -use-msasm -use-asm - add_ldflags -i-static - enabled x86_64 && add_cflags -ipo -no-prec-div -static -xSSE2 -axSSE2 + add_cflags -use-msasm # remove -use-msasm too? + # add -no-intel-extensions to suppress warning #10237 + # refer to http://software.intel.com/en-us/forums/topic/280199 + add_ldflags -i-static -no-intel-extensions + enabled x86_64 && add_cflags -ipo -static -O3 -no-prec-div enabled x86_64 && AR=xiar case ${tune_cpu} in atom*) @@ -1043,18 +1066,54 @@ EOF add_ldflags -m${bits} link_with_cc=gcc tune_cflags="-march=" - setup_gnu_toolchain + setup_gnu_toolchain #for 32 bit x86 builds, -O3 did not turn on this flag - enabled optimizations && check_add_cflags -fomit-frame-pointer + enabled optimizations && disabled gprof && check_add_cflags -fomit-frame-pointer ;; vs*) # When building with Microsoft Visual Studio the assembler is # invoked directly. Checking at configure time is unnecessary. # Skip the check by setting AS arbitrarily AS=msvs + msvs_arch_dir=x86-msvs + vc_version=${tgt_cc##vs} + case $vc_version in + 7|8|9|10) + echo "${tgt_cc} does not support avx/avx2, disabling....." + RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx --disable-avx2 " + soft_disable avx + soft_disable avx2 + ;; + esac ;; esac + soft_enable runtime_cpu_detect + soft_enable mmx + soft_enable sse + soft_enable sse2 + soft_enable sse3 + soft_enable ssse3 + # We can't use 'check_cflags' until the compiler is configured and CC is + # populated. + if enabled gcc && ! disabled sse4_1 && ! check_cflags -msse4; then + RTCD_OPTIONS="${RTCD_OPTIONS}--disable-sse4_1 " + else + soft_enable sse4_1 + fi + + if enabled gcc && ! disabled avx && ! check_cflags -mavx; then + RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx " + else + soft_enable avx + fi + + if enabled gcc && ! disabled avx2 && ! check_cflags -mavx2; then + RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx2 " + else + soft_enable avx2 + fi + case "${AS}" in auto|"") which nasm >/dev/null 2>&1 && AS=nasm @@ -1070,12 +1129,14 @@ EOF win32) add_asflags -f win32 enabled debug && add_asflags -g cv8 + EXE_SFX=.exe ;; win64) add_asflags -f x64 enabled debug && add_asflags -g cv8 + EXE_SFX=.exe ;; - linux*|solaris*) + linux*|solaris*|android*) add_asflags -f elf${bits} enabled debug && [ "${AS}" = yasm ] && add_asflags -g dwarf2 enabled debug && [ "${AS}" = nasm ] && add_asflags -g @@ -1103,7 +1164,7 @@ EOF ;; universal*|*-gcc|generic-gnu) link_with_cc=gcc - enable gcc + enable_feature gcc setup_gnu_toolchain ;; esac @@ -1137,6 +1198,12 @@ EOF fi fi + # default use_x86inc to yes if pic is no or 64bit or we are not on darwin + echo " checking here for x86inc \"${tgt_isa}\" \"$pic\" " + if [ ${tgt_isa} = x86_64 -o ! "$pic" = "yes" -o "${tgt_os#darwin}" = "${tgt_os}" ]; then + soft_enable use_x86inc + fi + # Position Independent Code (PIC) support, for building relocatable # shared objects enabled gcc && enabled pic && check_add_cflags -fPIC @@ -1146,14 +1213,22 @@ EOF enabled linux && check_add_cflags -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 # Check for strip utility variant - ${STRIP} -V 2>/dev/null | grep GNU >/dev/null && enable gnu_strip + ${STRIP} -V 2>/dev/null | grep GNU >/dev/null && enable_feature gnu_strip # Try to determine target endianness check_cc <<EOF unsigned int e = 'O'<<24 | '2'<<16 | 'B'<<8 | 'E'; EOF [ -f "${TMP_O}" ] && od -A n -t x1 "${TMP_O}" | tr -d '\n' | - grep '4f *32 *42 *45' >/dev/null 2>&1 && enable big_endian + grep '4f *32 *42 *45' >/dev/null 2>&1 && enable_feature big_endian + + # Try to find which inline keywords are supported + check_cc <<EOF && INLINE="inline" + static inline function() {} +EOF + check_cc <<EOF && INLINE="__inline__ __attribute__((always_inline))" + static __attribute__((always_inline)) function() {} +EOF # Almost every platform uses pthreads. if enabled multithread; then @@ -1170,15 +1245,12 @@ EOF if enabled dspr2; then if enabled big_endian; then echo "dspr2 optimizations are available only for little endian platforms" - disable dspr2 + disable_feature dspr2 fi fi ;; esac - # for sysconf(3) and friends. - check_header unistd.h - # glibc needs these if enabled linux; then add_cflags -D_LARGEFILE_SOURCE @@ -1224,8 +1296,8 @@ print_config_h() { print_webm_license() { local destination=$1 - local prefix=$2 - local suffix=$3 + local prefix="$2" + local suffix="$3" shift 3 cat <<EOF > ${destination} ${prefix} Copyright (c) 2011 The WebM project authors. All Rights Reserved.${suffix} @@ -1246,8 +1318,8 @@ process_detect() { true; } -enable logging -logfile="config.err" +enable_feature logging +logfile="config.log" self=$0 process() { cmdline_args="$@" diff --git a/build/make/gen_asm_deps.sh b/build/make/gen_asm_deps.sh index 0b4e3aa84..6a7bff9eb 100755 --- a/build/make/gen_asm_deps.sh +++ b/build/make/gen_asm_deps.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh ## ## Copyright (c) 2010 The WebM project authors. All Rights Reserved. ## diff --git a/build/make/gen_msvs_proj.sh b/build/make/gen_msvs_proj.sh index 6d429410d..fc5011bef 100755 --- a/build/make/gen_msvs_proj.sh +++ b/build/make/gen_msvs_proj.sh @@ -26,6 +26,7 @@ Options: --help Print this message --exe Generate a project for building an Application --lib Generate a project for creating a static library + --dll Generate a project for creating a dll --static-crt Use the static C runtime (/MT) --target=isa-os-cc Target specifier (required) --out=filename Write output to a file [stdout] @@ -142,7 +143,9 @@ generate_filter() { if [ "${f##*.}" == "$pat" ]; then unset file_list[i] + objf=$(echo ${f%.*}.obj | sed -e 's/^[\./]\+//g' -e 's,/,_,g') open_tag File RelativePath="./$f" + if [ "$pat" == "asm" ] && $asm_use_custom_step; then for plat in "${platforms[@]}"; do for cfg in Debug Release; do @@ -152,14 +155,27 @@ generate_filter() { tag Tool \ Name="VCCustomBuildTool" \ Description="Assembling \$(InputFileName)" \ - CommandLine="$(eval echo \$asm_${cfg}_cmdline)" \ - Outputs="\$(InputName).obj" \ + CommandLine="$(eval echo \$asm_${cfg}_cmdline) -o \$(IntDir)$objf" \ + Outputs="\$(IntDir)$objf" \ close_tag FileConfiguration done done fi + if [ "$pat" == "c" ] || [ "$pat" == "cc" ] ; then + for plat in "${platforms[@]}"; do + for cfg in Debug Release; do + open_tag FileConfiguration \ + Name="${cfg}|${plat}" \ + tag Tool \ + Name="VCCLCompilerTool" \ + ObjectFile="\$(IntDir)$objf" \ + + close_tag FileConfiguration + done + done + fi close_tag File break @@ -190,6 +206,8 @@ for opt in "$@"; do ;; --exe) proj_kind="exe" ;; + --dll) proj_kind="dll" + ;; --lib) proj_kind="lib" ;; --src-path-bare=*) src_path_bare="$optval" @@ -242,10 +260,15 @@ uses_asm=${uses_asm:-false} case "${vs_ver:-8}" in 7) vs_ver_id="7.10" asm_use_custom_step=$uses_asm + warn_64bit='Detect64BitPortabilityProblems=true' ;; 8) vs_ver_id="8.00" + asm_use_custom_step=$uses_asm + warn_64bit='Detect64BitPortabilityProblems=true' ;; 9) vs_ver_id="9.00" + asm_use_custom_step=$uses_asm + warn_64bit='Detect64BitPortabilityProblems=false' ;; esac @@ -284,10 +307,11 @@ esac case "$target" in x86_64*) platforms[0]="x64" + asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} "\$(InputPath)"" + asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} "\$(InputPath)"" ;; x86*) platforms[0]="Win32" - # these are only used by vs7 asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} "\$(InputPath)"" asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} "\$(InputPath)"" ;; @@ -299,6 +323,8 @@ generate_vcproj() { case "$proj_kind" in exe) vs_ConfigurationType=1 ;; + dll) vs_ConfigurationType=2 + ;; *) vs_ConfigurationType=4 ;; esac @@ -318,13 +344,6 @@ generate_vcproj() { done close_tag Platforms - open_tag ToolFiles - case "$target" in - x86*) $uses_asm && tag ToolFile RelativePath="$self_dirname/../x86-msvs/yasm.rules" - ;; - esac - close_tag ToolFiles - open_tag Configurations for plat in "${platforms[@]}"; do plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'` @@ -346,8 +365,8 @@ generate_vcproj() { PreprocessorDefinitions="WIN32;DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" \ RuntimeLibrary="$debug_runtime" \ WarningLevel="3" \ - Detect64BitPortabilityProblems="true" \ DebugInformationFormat="1" \ + $warn_64bit \ ;; vpx) tag Tool \ @@ -362,8 +381,8 @@ generate_vcproj() { RuntimeLibrary="$debug_runtime" \ UsePrecompiledHeader="0" \ WarningLevel="3" \ - DebugInformationFormat="1" \ - Detect64BitPortabilityProblems="true" \ + DebugInformationFormat="2" \ + $warn_64bit \ $uses_asm && tag Tool Name="YASM" IncludePaths="$incs" Debug="true" ;; @@ -376,8 +395,8 @@ generate_vcproj() { RuntimeLibrary="$debug_runtime" \ UsePrecompiledHeader="0" \ WarningLevel="3" \ - DebugInformationFormat="1" \ - Detect64BitPortabilityProblems="true" \ + DebugInformationFormat="2" \ + $warn_64bit \ $uses_asm && tag Tool Name="YASM" IncludePaths="$incs" Debug="true" ;; @@ -454,8 +473,8 @@ generate_vcproj() { RuntimeLibrary="$release_runtime" \ UsePrecompiledHeader="0" \ WarningLevel="3" \ - Detect64BitPortabilityProblems="true" \ DebugInformationFormat="0" \ + $warn_64bit \ ;; vpx) tag Tool \ @@ -472,7 +491,7 @@ generate_vcproj() { UsePrecompiledHeader="0" \ WarningLevel="3" \ DebugInformationFormat="0" \ - Detect64BitPortabilityProblems="true" \ + $warn_64bit \ $uses_asm && tag Tool Name="YASM" IncludePaths="$incs" ;; @@ -487,7 +506,7 @@ generate_vcproj() { UsePrecompiledHeader="0" \ WarningLevel="3" \ DebugInformationFormat="0" \ - Detect64BitPortabilityProblems="true" \ + $warn_64bit \ $uses_asm && tag Tool Name="YASM" IncludePaths="$incs" ;; diff --git a/build/make/gen_msvs_sln.sh b/build/make/gen_msvs_sln.sh index 240678b64..ffa370666 100755 --- a/build/make/gen_msvs_sln.sh +++ b/build/make/gen_msvs_sln.sh @@ -25,7 +25,7 @@ files. Options: --help Print this message --out=outfile Redirect output to a file - --ver=version Version (7,8,9) of visual studio to generate for + --ver=version Version (7,8,9,10,11) of visual studio to generate for --target=isa-os-cc Target specifier EOF exit 1 @@ -55,22 +55,38 @@ indent_pop() { parse_project() { local file=$1 - local name=`grep Name "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'` - local guid=`grep ProjectGUID "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'` + if [ "$sfx" = "vcproj" ]; then + local name=`grep Name "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'` + local guid=`grep ProjectGUID "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'` + else + local name=`grep RootNamespace "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'` + local guid=`grep ProjectGuid "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'` + fi # save the project GUID to a varaible, normalizing to the basename of the # vcproj file without the extension local var var=${file##*/} - var=${var%%.vcproj} + var=${var%%.${sfx}} eval "${var}_file=\"$1\"" eval "${var}_name=$name" eval "${var}_guid=$guid" - # assume that all projects have the same list of possible configurations, - # so overwriting old config_lists is not a problem - config_list=`grep -A1 '<Configuration' $file | - grep Name | cut -d\" -f2` + if [ "$sfx" = "vcproj" ]; then + cur_config_list=`grep -A1 '<Configuration' $file | + grep Name | cut -d\" -f2` + else + cur_config_list=`grep -B1 'Label="Configuration"' $file | + grep Condition | cut -d\' -f4` + fi + new_config_list=$(for i in $config_list $cur_config_list; do + echo $i + done | sort | uniq) + if [ "$config_list" != "" ] && [ "$config_list" != "$new_config_list" ]; then + mixed_platforms=1 + fi + config_list="$new_config_list" + eval "${var}_config_list=\"$cur_config_list\"" proj_list="${proj_list} ${var}" } @@ -83,14 +99,14 @@ process_project() { # vcproj file without the extension local var var=${file##*/} - var=${var%%.vcproj} + var=${var%%.${sfx}} eval "${var}_guid=$guid" echo "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$name\", \"$file\", \"$guid\"" indent_push eval "local deps=\"\${${var}_deps}\"" - if [ -n "$deps" ]; then + if [ -n "$deps" ] && [ "$sfx" = "vcproj" ]; then echo "${indent}ProjectSection(ProjectDependencies) = postProject" indent_push @@ -120,6 +136,11 @@ process_global() { indent_push IFS_bak=${IFS} IFS=$'\r'$'\n' + if [ "$mixed_platforms" != "" ]; then + config_list=" +Release|Mixed Platforms +Debug|Mixed Platforms" + fi for config in ${config_list}; do echo "${indent}$config = $config" done @@ -134,10 +155,17 @@ process_global() { indent_push for proj in ${proj_list}; do eval "local proj_guid=\${${proj}_guid}" + eval "local proj_config_list=\${${proj}_config_list}" IFS=$'\r'$'\n' - for config in ${config_list}; do - echo "${indent}${proj_guid}.${config}.ActiveCfg = ${config}" - echo "${indent}${proj_guid}.${config}.Build.0 = ${config}" + for config in ${proj_config_list}; do + if [ "$mixed_platforms" != "" ]; then + local c=${config%%|*} + echo "${indent}${proj_guid}.${c}|Mixed Platforms.ActiveCfg = ${config}" + echo "${indent}${proj_guid}.${c}|Mixed Platforms.Build.0 = ${config}" + else + echo "${indent}${proj_guid}.${config}.ActiveCfg = ${config}" + echo "${indent}${proj_guid}.${config}.Build.0 = ${config}" + fi done IFS=${IFS_bak} @@ -163,9 +191,14 @@ process_makefile() { IFS=$'\r'$'\n' local TAB=$'\t' cat <<EOF -found_devenv := \$(shell which devenv.com >/dev/null 2>&1 && echo yes) +ifeq (\$(CONFIG_VS_VERSION),7) +MSBUILD_TOOL := devenv.com +else +MSBUILD_TOOL := msbuild.exe +endif +found_devenv := \$(shell which \$(MSBUILD_TOOL) >/dev/null 2>&1 && echo yes) .nodevenv.once: -${TAB}@echo " * devenv.com not found in path." +${TAB}@echo " * \$(MSBUILD_TOOL) not found in path." ${TAB}@echo " * " ${TAB}@echo " * You will have to build all configurations manually using the" ${TAB}@echo " * Visual Studio IDE. To allow make to build them automatically," @@ -190,16 +223,17 @@ ${TAB}rm -rf "$platform"/"$config" ifneq (\$(found_devenv),) ifeq (\$(CONFIG_VS_VERSION),7) $nows_sln_config: $outfile -${TAB}devenv.com $outfile -build "$config" +${TAB}\$(MSBUILD_TOOL) $outfile -build "$config" else $nows_sln_config: $outfile -${TAB}devenv.com $outfile -build "$sln_config" +${TAB}\$(MSBUILD_TOOL) $outfile -m -t:Build \\ +${TAB}${TAB}-p:Configuration="$config" -p:Platform="$platform" endif else $nows_sln_config: $outfile .nodevenv.once -${TAB}@echo " * Skipping build of $sln_config (devenv.com not in path)." +${TAB}@echo " * Skipping build of $sln_config (\$(MSBUILD_TOOL) not in path)." ${TAB}@echo " * " endif @@ -221,7 +255,7 @@ for opt in "$@"; do ;; --ver=*) vs_ver="$optval" case $optval in - [789]) + [789]|10|11|12) ;; *) die Unrecognized Visual Studio Version in $opt ;; @@ -257,6 +291,23 @@ case "${vs_ver:-8}" in 9) sln_vers="10.00" sln_vers_str="Visual Studio 2008" ;; + 10) sln_vers="11.00" + sln_vers_str="Visual Studio 2010" + ;; + 11) sln_vers="12.00" + sln_vers_str="Visual Studio 2012" + ;; + 12) sln_vers="12.00" + sln_vers_str="Visual Studio 2013" + ;; +esac +case "${vs_ver:-8}" in + [789]) + sfx=vcproj + ;; + 10|11|12) + sfx=vcxproj + ;; esac for f in "${file_list[@]}"; do diff --git a/build/make/gen_msvs_vcxproj.sh b/build/make/gen_msvs_vcxproj.sh new file mode 100755 index 000000000..359157c22 --- /dev/null +++ b/build/make/gen_msvs_vcxproj.sh @@ -0,0 +1,544 @@ +#!/bin/bash +## +## Copyright (c) 2013 The WebM project authors. All Rights Reserved. +## +## Use of this source code is governed by a BSD-style license +## that can be found in the LICENSE file in the root of the source +## tree. An additional intellectual property rights grant can be found +## in the file PATENTS. All contributing project authors may +## be found in the AUTHORS file in the root of the source tree. +## + + +self=$0 +self_basename=${self##*/} +self_dirname=$(dirname "$0") +EOL=$'\n' + +show_help() { + cat <<EOF +Usage: ${self_basename} --name=projname [options] file1 [file2 ...] + +This script generates a Visual Studio project file from a list of source +code files. + +Options: + --help Print this message + --exe Generate a project for building an Application + --lib Generate a project for creating a static library + --dll Generate a project for creating a dll + --static-crt Use the static C runtime (/MT) + --target=isa-os-cc Target specifier (required) + --out=filename Write output to a file [stdout] + --name=project_name Name of the project (required) + --proj-guid=GUID GUID to use for the project + --module-def=filename File containing export definitions (for DLLs) + --ver=version Version (10,11,12) of visual studio to generate for + --src-path-bare=dir Path to root of source tree + -Ipath/to/include Additional include directories + -DFLAG[=value] Preprocessor macros to define + -Lpath/to/lib Additional library search paths + -llibname Library to link against +EOF + exit 1 +} + +die() { + echo "${self_basename}: $@" >&2 + exit 1 +} + +die_unknown(){ + echo "Unknown option \"$1\"." >&2 + echo "See ${self_basename} --help for available options." >&2 + exit 1 +} + +generate_uuid() { + local hex="0123456789ABCDEF" + local i + local uuid="" + local j + #93995380-89BD-4b04-88EB-625FBE52EBFB + for ((i=0; i<32; i++)); do + (( j = $RANDOM % 16 )) + uuid="${uuid}${hex:$j:1}" + done + echo "${uuid:0:8}-${uuid:8:4}-${uuid:12:4}-${uuid:16:4}-${uuid:20:12}" +} + +indent1=" " +indent="" +indent_push() { + indent="${indent}${indent1}" +} +indent_pop() { + indent="${indent%${indent1}}" +} + +tag_attributes() { + for opt in "$@"; do + optval="${opt#*=}" + [ -n "${optval}" ] || + die "Missing attribute value in '$opt' while generating $tag tag" + echo "${indent}${opt%%=*}=\"${optval}\"" + done +} + +open_tag() { + local tag=$1 + shift + if [ $# -ne 0 ]; then + echo "${indent}<${tag}" + indent_push + tag_attributes "$@" + echo "${indent}>" + else + echo "${indent}<${tag}>" + indent_push + fi +} + +close_tag() { + local tag=$1 + indent_pop + echo "${indent}</${tag}>" +} + +tag() { + local tag=$1 + shift + if [ $# -ne 0 ]; then + echo "${indent}<${tag}" + indent_push + tag_attributes "$@" + indent_pop + echo "${indent}/>" + else + echo "${indent}<${tag}/>" + fi +} + +tag_content() { + local tag=$1 + local content=$2 + shift + shift + if [ $# -ne 0 ]; then + echo "${indent}<${tag}" + indent_push + tag_attributes "$@" + echo "${indent}>${content}</${tag}>" + indent_pop + else + echo "${indent}<${tag}>${content}</${tag}>" + fi +} + +generate_filter() { + local name=$1 + local pats=$2 + local file_list_sz + local i + local f + local saveIFS="$IFS" + local pack + echo "generating filter '$name' from ${#file_list[@]} files" >&2 + IFS=* + + file_list_sz=${#file_list[@]} + for i in ${!file_list[@]}; do + f=${file_list[i]} + for pat in ${pats//;/$IFS}; do + if [ "${f##*.}" == "$pat" ]; then + unset file_list[i] + + objf=$(echo ${f%.*}.obj | sed -e 's/^[\./]\+//g' -e 's,/,_,g') + + if ([ "$pat" == "asm" ] || [ "$pat" == "s" ]) && $asm_use_custom_step; then + open_tag CustomBuild \ + Include=".\\$f" + for plat in "${platforms[@]}"; do + for cfg in Debug Release; do + tag_content Message "Assembling %(Filename)%(Extension)" \ + Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'" + tag_content Command "$(eval echo \$asm_${cfg}_cmdline) -o \$(IntDir)$objf" \ + Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'" + tag_content Outputs "\$(IntDir)$objf" \ + Condition="'\$(Configuration)|\$(Platform)'=='$cfg|$plat'" + done + done + close_tag CustomBuild + elif [ "$pat" == "c" ] || [ "$pat" == "cc" ] ; then + open_tag ClCompile \ + Include=".\\$f" + # Separate file names with Condition? + tag_content ObjectFileName "\$(IntDir)$objf" + close_tag ClCompile + elif [ "$pat" == "h" ] ; then + tag ClInclude \ + Include=".\\$f" + elif [ "$pat" == "vcxproj" ] ; then + open_tag ProjectReference \ + Include="$f" + depguid=`grep ProjectGuid "$f" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'` + tag_content Project "$depguid" + tag_content ReferenceOutputAssembly false + close_tag ProjectReference + else + tag None \ + Include=".\\$f" + fi + + break + fi + done + done + + IFS="$saveIFS" +} + +# Process command line +unset target +for opt in "$@"; do + optval="${opt#*=}" + case "$opt" in + --help|-h) show_help + ;; + --target=*) target="${optval}" + ;; + --out=*) outfile="$optval" + ;; + --name=*) name="${optval}" + ;; + --proj-guid=*) guid="${optval}" + ;; + --module-def=*) module_def="${optval}" + ;; + --exe) proj_kind="exe" + ;; + --dll) proj_kind="dll" + ;; + --lib) proj_kind="lib" + ;; + --src-path-bare=*) src_path_bare="$optval" + ;; + --static-crt) use_static_runtime=true + ;; + --ver=*) + vs_ver="$optval" + case "$optval" in + 10|11|12) + ;; + *) die Unrecognized Visual Studio Version in $opt + ;; + esac + ;; + -I*) + opt="${opt%/}" + incs="${incs}${incs:+;}${opt##-I}" + yasmincs="${yasmincs} ${opt}" + ;; + -D*) defines="${defines}${defines:+;}${opt##-D}" + ;; + -L*) # fudge . to $(OutDir) + if [ "${opt##-L}" == "." ]; then + libdirs="${libdirs}${libdirs:+;}\$(OutDir)" + else + # Also try directories for this platform/configuration + libdirs="${libdirs}${libdirs:+;}${opt##-L}" + libdirs="${libdirs}${libdirs:+;}${opt##-L}/\$(PlatformName)/\$(Configuration)" + libdirs="${libdirs}${libdirs:+;}${opt##-L}/\$(PlatformName)" + fi + ;; + -l*) libs="${libs}${libs:+ }${opt##-l}.lib" + ;; + -*) die_unknown $opt + ;; + *) + file_list[${#file_list[@]}]="$opt" + case "$opt" in + *.asm|*.s) uses_asm=true + ;; + esac + ;; + esac +done +outfile=${outfile:-/dev/stdout} +guid=${guid:-`generate_uuid`} +asm_use_custom_step=false +uses_asm=${uses_asm:-false} +case "${vs_ver:-11}" in + 10|11|12) + asm_use_custom_step=$uses_asm + ;; +esac + +[ -n "$name" ] || die "Project name (--name) must be specified!" +[ -n "$target" ] || die "Target (--target) must be specified!" + +if ${use_static_runtime:-false}; then + release_runtime=MultiThreaded + debug_runtime=MultiThreadedDebug + lib_sfx=mt +else + release_runtime=MultiThreadedDLL + debug_runtime=MultiThreadedDebugDLL + lib_sfx=md +fi + +# Calculate debug lib names: If a lib ends in ${lib_sfx}.lib, then rename +# it to ${lib_sfx}d.lib. This precludes linking to release libs from a +# debug exe, so this may need to be refactored later. +for lib in ${libs}; do + if [ "$lib" != "${lib%${lib_sfx}.lib}" ]; then + lib=${lib%.lib}d.lib + fi + debug_libs="${debug_libs}${debug_libs:+ }${lib}" +done +debug_libs=${debug_libs// /;} +libs=${libs// /;} + + +# List of all platforms supported for this target +case "$target" in + x86_64*) + platforms[0]="x64" + asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} "%(FullPath)"" + asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} "%(FullPath)"" + ;; + x86*) + platforms[0]="Win32" + asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} "%(FullPath)"" + asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} "%(FullPath)"" + ;; + arm*) + asm_Debug_cmdline="armasm -nologo "%(FullPath)"" + asm_Release_cmdline="armasm -nologo "%(FullPath)"" + if [ "$name" = "obj_int_extract" ]; then + # We don't want to build this tool for the target architecture, + # but for an architecture we can run locally during the build. + platforms[0]="Win32" + else + platforms[0]="ARM" + fi + ;; + *) die "Unsupported target $target!" + ;; +esac + +generate_vcxproj() { + echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + open_tag Project \ + DefaultTargets="Build" \ + ToolsVersion="4.0" \ + xmlns="http://schemas.microsoft.com/developer/msbuild/2003" \ + + open_tag ItemGroup \ + Label="ProjectConfigurations" + for plat in "${platforms[@]}"; do + for config in Debug Release; do + open_tag ProjectConfiguration \ + Include="$config|$plat" + tag_content Configuration $config + tag_content Platform $plat + close_tag ProjectConfiguration + done + done + close_tag ItemGroup + + open_tag PropertyGroup \ + Label="Globals" + tag_content ProjectGuid "{${guid}}" + tag_content RootNamespace ${name} + tag_content Keyword ManagedCProj + close_tag PropertyGroup + + tag Import \ + Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" + + for plat in "${platforms[@]}"; do + for config in Release Debug; do + open_tag PropertyGroup \ + Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'" \ + Label="Configuration" + if [ "$proj_kind" = "exe" ]; then + tag_content ConfigurationType Application + elif [ "$proj_kind" = "dll" ]; then + tag_content ConfigurationType DynamicLibrary + else + tag_content ConfigurationType StaticLibrary + fi + if [ "$vs_ver" = "11" ]; then + if [ "$plat" = "ARM" ]; then + # Setting the wp80 toolchain automatically sets the + # WINAPI_FAMILY define, which is required for building + # code for arm with the windows headers. Alternatively, + # one could add AppContainerApplication=true in the Globals + # section and add PrecompiledHeader=NotUsing and + # CompileAsWinRT=false in ClCompile and SubSystem=Console + # in Link. + tag_content PlatformToolset v110_wp80 + else + tag_content PlatformToolset v110 + fi + fi + if [ "$vs_ver" = "12" ]; then + if [ "$plat" = "ARM" ]; then + # Setting the wp80 toolchain automatically sets the + # WINAPI_FAMILY define, which is required for building + # code for arm with the windows headers. Alternatively, + # one could add AppContainerApplication=true in the Globals + # section and add PrecompiledHeader=NotUsing and + # CompileAsWinRT=false in ClCompile and SubSystem=Console + # in Link. + tag_content PlatformToolset v120_wp80 + else + tag_content PlatformToolset v120 + fi + fi + tag_content CharacterSet Unicode + if [ "$config" = "Release" ]; then + tag_content WholeProgramOptimization true + fi + close_tag PropertyGroup + done + done + + tag Import \ + Project="\$(VCTargetsPath)\\Microsoft.Cpp.props" + + open_tag ImportGroup \ + Label="PropertySheets" + tag Import \ + Project="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" \ + Condition="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" \ + Label="LocalAppDataPlatform" + close_tag ImportGroup + + tag PropertyGroup \ + Label="UserMacros" + + for plat in "${platforms[@]}"; do + plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'` + for config in Debug Release; do + open_tag PropertyGroup \ + Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'" + tag_content OutDir "\$(SolutionDir)$plat_no_ws\\\$(Configuration)\\" + tag_content IntDir "$plat_no_ws\\\$(Configuration)\\${name}\\" + close_tag PropertyGroup + done + done + + for plat in "${platforms[@]}"; do + for config in Debug Release; do + open_tag ItemDefinitionGroup \ + Condition="'\$(Configuration)|\$(Platform)'=='$config|$plat'" + if [ "$name" = "vpx" ]; then + open_tag PreBuildEvent + tag_content Command "call obj_int_extract.bat $src_path_bare" + close_tag PreBuildEvent + fi + open_tag ClCompile + if [ "$config" = "Debug" ]; then + opt=Disabled + runtime=$debug_runtime + curlibs=$debug_libs + confsuffix=d + case "$name" in + obj_int_extract) + debug=DEBUG + ;; + *) + debug=_DEBUG + ;; + esac + else + opt=MaxSpeed + runtime=$release_runtime + curlibs=$libs + confsuffix="" + tag_content FavorSizeOrSpeed Speed + debug=NDEBUG + fi + case "$name" in + obj_int_extract) + extradefines=";_CONSOLE" + ;; + *) + extradefines=";$defines" + ;; + esac + tag_content Optimization $opt + tag_content AdditionalIncludeDirectories "$incs;%(AdditionalIncludeDirectories)" + tag_content PreprocessorDefinitions "WIN32;$debug;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE$extradefines;%(PreprocessorDefinitions)" + tag_content RuntimeLibrary $runtime + tag_content WarningLevel Level3 + # DebugInformationFormat + close_tag ClCompile + case "$proj_kind" in + exe) + open_tag Link + if [ "$name" = "obj_int_extract" ]; then + tag_content OutputFile "${name}.exe" + else + tag_content AdditionalDependencies "$curlibs" + tag_content AdditionalLibraryDirectories "$libdirs;%(AdditionalLibraryDirectories)" + fi + tag_content GenerateDebugInformation true + close_tag Link + ;; + dll) + open_tag Link + tag_content GenerateDebugInformation true + tag_content ModuleDefinitionFile $module_def + close_tag Link + ;; + lib) + open_tag Lib + tag_content OutputFile "\$(OutDir)${name}${lib_sfx}${confsuffix}.lib" + close_tag Lib + ;; + esac + close_tag ItemDefinitionGroup + done + + done + + open_tag ItemGroup + generate_filter "Source Files" "c;cc;def;odl;idl;hpj;bat;asm;asmx;s" + close_tag ItemGroup + open_tag ItemGroup + generate_filter "Header Files" "h;hm;inl;inc;xsd" + close_tag ItemGroup + open_tag ItemGroup + generate_filter "Build Files" "mk" + close_tag ItemGroup + open_tag ItemGroup + generate_filter "References" "vcxproj" + close_tag ItemGroup + + tag Import \ + Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets" + + open_tag ImportGroup \ + Label="ExtensionTargets" + close_tag ImportGroup + + close_tag Project + + # This must be done from within the {} subshell + echo "Ignored files list (${#file_list[@]} items) is:" >&2 + for f in "${file_list[@]}"; do + echo " $f" >&2 + done +} + +# This regexp doesn't catch most of the strings in the vcxproj format, +# since they're like <tag>path</tag> instead of <tag attr="path" /> +# as previously. It still seems to work ok despite this. +generate_vcxproj | + sed -e '/"/s;\([^ "]\)/;\1\\;g' | + sed -e '/xmlns/s;\\;/;g' > ${outfile} + +exit diff --git a/build/make/obj_int_extract.c b/build/make/obj_int_extract.c index bf317bd7b..feed9d983 100644 --- a/build/make/obj_int_extract.c +++ b/build/make/obj_int_extract.c @@ -17,21 +17,19 @@ #include "vpx_config.h" #include "vpx/vpx_integer.h" -typedef enum -{ - OUTPUT_FMT_PLAIN, - OUTPUT_FMT_RVDS, - OUTPUT_FMT_GAS, +typedef enum { + OUTPUT_FMT_PLAIN, + OUTPUT_FMT_RVDS, + OUTPUT_FMT_GAS, } output_fmt_t; -int log_msg(const char *fmt, ...) -{ - int res; - va_list ap; - va_start(ap, fmt); - res = vfprintf(stderr, fmt, ap); - va_end(ap); - return res; +int log_msg(const char *fmt, ...) { + int res; + va_list ap; + va_start(ap, fmt); + res = vfprintf(stderr, fmt, ap); + va_end(ap); + return res; } #if defined(__GNUC__) && __GNUC__ @@ -40,175 +38,160 @@ int log_msg(const char *fmt, ...) #include <mach-o/loader.h> #include <mach-o/nlist.h> -int parse_macho(uint8_t *base_buf, size_t sz) -{ - int i, j; - struct mach_header header; - uint8_t *buf = base_buf; - int base_data_section = 0; - int bits = 0; - - /* We can read in mach_header for 32 and 64 bit architectures - * because it's identical to mach_header_64 except for the last - * element (uint32_t reserved), which we don't use. Then, when - * we know which architecture we're looking at, increment buf - * appropriately. - */ - memcpy(&header, buf, sizeof(struct mach_header)); - - if (header.magic == MH_MAGIC) - { - if (header.cputype == CPU_TYPE_ARM - || header.cputype == CPU_TYPE_X86) - { - bits = 32; - buf += sizeof(struct mach_header); - } - else - { - log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_[ARM|X86].\n"); - goto bail; - } +int print_macho_equ(output_fmt_t mode, uint8_t* name, int val) { + switch (mode) { + case OUTPUT_FMT_RVDS: + printf("%-40s EQU %5d\n", name, val); + return 0; + case OUTPUT_FMT_GAS: + printf(".set %-40s, %5d\n", name, val); + return 0; + default: + log_msg("Unsupported mode: %d", mode); + return 1; + } +} + +int parse_macho(uint8_t *base_buf, size_t sz, output_fmt_t mode) { + int i, j; + struct mach_header header; + uint8_t *buf = base_buf; + int base_data_section = 0; + int bits = 0; + + /* We can read in mach_header for 32 and 64 bit architectures + * because it's identical to mach_header_64 except for the last + * element (uint32_t reserved), which we don't use. Then, when + * we know which architecture we're looking at, increment buf + * appropriately. + */ + memcpy(&header, buf, sizeof(struct mach_header)); + + if (header.magic == MH_MAGIC) { + if (header.cputype == CPU_TYPE_ARM + || header.cputype == CPU_TYPE_X86) { + bits = 32; + buf += sizeof(struct mach_header); + } else { + log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_[ARM|X86].\n"); + goto bail; } - else if (header.magic == MH_MAGIC_64) - { - if (header.cputype == CPU_TYPE_X86_64) - { - bits = 64; - buf += sizeof(struct mach_header_64); - } - else - { - log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_X86_64.\n"); - goto bail; - } + } else if (header.magic == MH_MAGIC_64) { + if (header.cputype == CPU_TYPE_X86_64) { + bits = 64; + buf += sizeof(struct mach_header_64); + } else { + log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_X86_64.\n"); + goto bail; } - else - { - log_msg("Bad magic number for object file. 0x%x or 0x%x expected, 0x%x found.\n", - MH_MAGIC, MH_MAGIC_64, header.magic); + } else { + log_msg("Bad magic number for object file. 0x%x or 0x%x expected, 0x%x found.\n", + MH_MAGIC, MH_MAGIC_64, header.magic); + goto bail; + } + + if (header.filetype != MH_OBJECT) { + log_msg("Bad filetype for object file. Currently only tested for MH_OBJECT.\n"); + goto bail; + } + + for (i = 0; i < header.ncmds; i++) { + struct load_command lc; + + memcpy(&lc, buf, sizeof(struct load_command)); + + if (lc.cmd == LC_SEGMENT) { + uint8_t *seg_buf = buf; + struct section s; + struct segment_command seg_c; + + memcpy(&seg_c, seg_buf, sizeof(struct segment_command)); + seg_buf += sizeof(struct segment_command); + + /* Although each section is given it's own offset, nlist.n_value + * references the offset of the first section. This isn't + * apparent without debug information because the offset of the + * data section is the same as the first section. However, with + * debug sections mixed in, the offset of the debug section + * increases but n_value still references the first section. + */ + if (seg_c.nsects < 1) { + log_msg("Not enough sections\n"); goto bail; - } + } - if (header.filetype != MH_OBJECT) - { - log_msg("Bad filetype for object file. Currently only tested for MH_OBJECT.\n"); + memcpy(&s, seg_buf, sizeof(struct section)); + base_data_section = s.offset; + } else if (lc.cmd == LC_SEGMENT_64) { + uint8_t *seg_buf = buf; + struct section_64 s; + struct segment_command_64 seg_c; + + memcpy(&seg_c, seg_buf, sizeof(struct segment_command_64)); + seg_buf += sizeof(struct segment_command_64); + + /* Explanation in LG_SEGMENT */ + if (seg_c.nsects < 1) { + log_msg("Not enough sections\n"); goto bail; - } + } - for (i = 0; i < header.ncmds; i++) - { - struct load_command lc; - - memcpy(&lc, buf, sizeof(struct load_command)); - - if (lc.cmd == LC_SEGMENT) - { - uint8_t *seg_buf = buf; - struct section s; - struct segment_command seg_c; - - memcpy(&seg_c, seg_buf, sizeof(struct segment_command)); - seg_buf += sizeof(struct segment_command); - - /* Although each section is given it's own offset, nlist.n_value - * references the offset of the first section. This isn't - * apparent without debug information because the offset of the - * data section is the same as the first section. However, with - * debug sections mixed in, the offset of the debug section - * increases but n_value still references the first section. - */ - if (seg_c.nsects < 1) - { - log_msg("Not enough sections\n"); - goto bail; - } + memcpy(&s, seg_buf, sizeof(struct section_64)); + base_data_section = s.offset; + } else if (lc.cmd == LC_SYMTAB) { + if (base_data_section != 0) { + struct symtab_command sc; + uint8_t *sym_buf = base_buf; + uint8_t *str_buf = base_buf; - memcpy(&s, seg_buf, sizeof(struct section)); - base_data_section = s.offset; - } - else if (lc.cmd == LC_SEGMENT_64) - { - uint8_t *seg_buf = buf; - struct section_64 s; - struct segment_command_64 seg_c; - - memcpy(&seg_c, seg_buf, sizeof(struct segment_command_64)); - seg_buf += sizeof(struct segment_command_64); - - /* Explanation in LG_SEGMENT */ - if (seg_c.nsects < 1) - { - log_msg("Not enough sections\n"); - goto bail; - } + memcpy(&sc, buf, sizeof(struct symtab_command)); - memcpy(&s, seg_buf, sizeof(struct section_64)); - base_data_section = s.offset; - } - else if (lc.cmd == LC_SYMTAB) - { - if (base_data_section != 0) - { - struct symtab_command sc; - uint8_t *sym_buf = base_buf; - uint8_t *str_buf = base_buf; - - memcpy(&sc, buf, sizeof(struct symtab_command)); - - if (sc.cmdsize != sizeof(struct symtab_command)) - { - log_msg("Can't find symbol table!\n"); - goto bail; - } - - sym_buf += sc.symoff; - str_buf += sc.stroff; - - for (j = 0; j < sc.nsyms; j++) - { - /* Location of string is cacluated each time from the - * start of the string buffer. On darwin the symbols - * are prefixed by "_", so we bump the pointer by 1. - * The target value is defined as an int in asm_*_offsets.c, - * which is 4 bytes on all targets we currently use. - */ - if (bits == 32) - { - struct nlist nl; - int val; - - memcpy(&nl, sym_buf, sizeof(struct nlist)); - sym_buf += sizeof(struct nlist); - - memcpy(&val, base_buf + base_data_section + nl.n_value, - sizeof(val)); - printf("%-40s EQU %5d\n", - str_buf + nl.n_un.n_strx + 1, val); - } - else /* if (bits == 64) */ - { - struct nlist_64 nl; - int val; - - memcpy(&nl, sym_buf, sizeof(struct nlist_64)); - sym_buf += sizeof(struct nlist_64); - - memcpy(&val, base_buf + base_data_section + nl.n_value, - sizeof(val)); - printf("%-40s EQU %5d\n", - str_buf + nl.n_un.n_strx + 1, val); - } - } - } + if (sc.cmdsize != sizeof(struct symtab_command)) { + log_msg("Can't find symbol table!\n"); + goto bail; } - buf += lc.cmdsize; + sym_buf += sc.symoff; + str_buf += sc.stroff; + + for (j = 0; j < sc.nsyms; j++) { + /* Location of string is cacluated each time from the + * start of the string buffer. On darwin the symbols + * are prefixed by "_", so we bump the pointer by 1. + * The target value is defined as an int in *_asm_*_offsets.c, + * which is 4 bytes on all targets we currently use. + */ + if (bits == 32) { + struct nlist nl; + int val; + + memcpy(&nl, sym_buf, sizeof(struct nlist)); + sym_buf += sizeof(struct nlist); + + memcpy(&val, base_buf + base_data_section + nl.n_value, + sizeof(val)); + print_macho_equ(mode, str_buf + nl.n_un.n_strx + 1, val); + } else { /* if (bits == 64) */ + struct nlist_64 nl; + int val; + + memcpy(&nl, sym_buf, sizeof(struct nlist_64)); + sym_buf += sizeof(struct nlist_64); + + memcpy(&val, base_buf + base_data_section + nl.n_value, + sizeof(val)); + print_macho_equ(mode, str_buf + nl.n_un.n_strx + 1, val); + } + } + } } - return 0; + buf += lc.cmdsize; + } + + return 0; bail: - return 1; + return 1; } @@ -216,448 +199,400 @@ bail: #include "elf.h" #define COPY_STRUCT(dst, buf, ofst, sz) do {\ - if(ofst + sizeof((*(dst))) > sz) goto bail;\ - memcpy(dst, buf+ofst, sizeof((*(dst))));\ - } while(0) + if(ofst + sizeof((*(dst))) > sz) goto bail;\ + memcpy(dst, buf+ofst, sizeof((*(dst))));\ + } while(0) #define ENDIAN_ASSIGN(val, memb) do {\ - if(!elf->le_data) {log_msg("Big Endian data not supported yet!\n");goto bail;}\ - (val) = (memb);\ - } while(0) + if(!elf->le_data) {log_msg("Big Endian data not supported yet!\n");goto bail;}\ + (val) = (memb);\ + } while(0) #define ENDIAN_ASSIGN_IN_PLACE(memb) do {\ - ENDIAN_ASSIGN(memb, memb);\ - } while(0) - -typedef struct -{ - uint8_t *buf; /* Buffer containing ELF data */ - size_t sz; /* Buffer size */ - int le_data; /* Data is little-endian */ - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - int bits; /* 32 or 64 */ - Elf32_Ehdr hdr32; - Elf64_Ehdr hdr64; + ENDIAN_ASSIGN(memb, memb);\ + } while(0) + +typedef struct { + uint8_t *buf; /* Buffer containing ELF data */ + size_t sz; /* Buffer size */ + int le_data; /* Data is little-endian */ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + int bits; /* 32 or 64 */ + Elf32_Ehdr hdr32; + Elf64_Ehdr hdr64; } elf_obj_t; -int parse_elf_header(elf_obj_t *elf) -{ - int res; - /* Verify ELF Magic numbers */ - COPY_STRUCT(&elf->e_ident, elf->buf, 0, elf->sz); - res = elf->e_ident[EI_MAG0] == ELFMAG0; - res &= elf->e_ident[EI_MAG1] == ELFMAG1; - res &= elf->e_ident[EI_MAG2] == ELFMAG2; - res &= elf->e_ident[EI_MAG3] == ELFMAG3; - res &= elf->e_ident[EI_CLASS] == ELFCLASS32 - || elf->e_ident[EI_CLASS] == ELFCLASS64; - res &= elf->e_ident[EI_DATA] == ELFDATA2LSB; - - if (!res) goto bail; - - elf->le_data = elf->e_ident[EI_DATA] == ELFDATA2LSB; - - /* Read in relevant values */ - if (elf->e_ident[EI_CLASS] == ELFCLASS32) - { - elf->bits = 32; - COPY_STRUCT(&elf->hdr32, elf->buf, 0, elf->sz); - - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_type); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_machine); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_version); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_entry); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phoff); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shoff); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_flags); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_ehsize); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phentsize); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phnum); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shentsize); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shnum); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shstrndx); - } - else /* if (elf->e_ident[EI_CLASS] == ELFCLASS64) */ - { - elf->bits = 64; - COPY_STRUCT(&elf->hdr64, elf->buf, 0, elf->sz); - - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_type); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_machine); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_version); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_entry); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phoff); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shoff); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_flags); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_ehsize); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phentsize); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phnum); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shentsize); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shnum); - ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shstrndx); - } - - return 0; +int parse_elf_header(elf_obj_t *elf) { + int res; + /* Verify ELF Magic numbers */ + COPY_STRUCT(&elf->e_ident, elf->buf, 0, elf->sz); + res = elf->e_ident[EI_MAG0] == ELFMAG0; + res &= elf->e_ident[EI_MAG1] == ELFMAG1; + res &= elf->e_ident[EI_MAG2] == ELFMAG2; + res &= elf->e_ident[EI_MAG3] == ELFMAG3; + res &= elf->e_ident[EI_CLASS] == ELFCLASS32 + || elf->e_ident[EI_CLASS] == ELFCLASS64; + res &= elf->e_ident[EI_DATA] == ELFDATA2LSB; + + if (!res) goto bail; + + elf->le_data = elf->e_ident[EI_DATA] == ELFDATA2LSB; + + /* Read in relevant values */ + if (elf->e_ident[EI_CLASS] == ELFCLASS32) { + elf->bits = 32; + COPY_STRUCT(&elf->hdr32, elf->buf, 0, elf->sz); + + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_type); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_machine); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_version); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_entry); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phoff); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shoff); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_flags); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_ehsize); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phentsize); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phnum); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shentsize); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shnum); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shstrndx); + } else { /* if (elf->e_ident[EI_CLASS] == ELFCLASS64) */ + elf->bits = 64; + COPY_STRUCT(&elf->hdr64, elf->buf, 0, elf->sz); + + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_type); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_machine); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_version); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_entry); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phoff); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shoff); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_flags); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_ehsize); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phentsize); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phnum); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shentsize); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shnum); + ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shstrndx); + } + + return 0; bail: - log_msg("Failed to parse ELF file header"); - return 1; + log_msg("Failed to parse ELF file header"); + return 1; } -int parse_elf_section(elf_obj_t *elf, int idx, Elf32_Shdr *hdr32, Elf64_Shdr *hdr64) -{ - if (hdr32) - { - if (idx >= elf->hdr32.e_shnum) - goto bail; - - COPY_STRUCT(hdr32, elf->buf, elf->hdr32.e_shoff + idx * elf->hdr32.e_shentsize, - elf->sz); - ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_name); - ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_type); - ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_flags); - ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addr); - ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_offset); - ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_size); - ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_link); - ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_info); - ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addralign); - ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_entsize); - } - else /* if (hdr64) */ - { - if (idx >= elf->hdr64.e_shnum) - goto bail; - - COPY_STRUCT(hdr64, elf->buf, elf->hdr64.e_shoff + idx * elf->hdr64.e_shentsize, - elf->sz); - ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_name); - ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_type); - ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_flags); - ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addr); - ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_offset); - ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_size); - ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_link); - ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_info); - ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addralign); - ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_entsize); - } +int parse_elf_section(elf_obj_t *elf, int idx, Elf32_Shdr *hdr32, Elf64_Shdr *hdr64) { + if (hdr32) { + if (idx >= elf->hdr32.e_shnum) + goto bail; - return 0; + COPY_STRUCT(hdr32, elf->buf, elf->hdr32.e_shoff + idx * elf->hdr32.e_shentsize, + elf->sz); + ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_name); + ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_type); + ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_flags); + ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addr); + ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_offset); + ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_size); + ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_link); + ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_info); + ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addralign); + ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_entsize); + } else { /* if (hdr64) */ + if (idx >= elf->hdr64.e_shnum) + goto bail; + + COPY_STRUCT(hdr64, elf->buf, elf->hdr64.e_shoff + idx * elf->hdr64.e_shentsize, + elf->sz); + ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_name); + ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_type); + ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_flags); + ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addr); + ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_offset); + ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_size); + ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_link); + ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_info); + ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addralign); + ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_entsize); + } + + return 0; bail: - return 1; + return 1; } -char *parse_elf_string_table(elf_obj_t *elf, int s_idx, int idx) -{ - if (elf->bits == 32) - { - Elf32_Shdr shdr; - - if (parse_elf_section(elf, s_idx, &shdr, NULL)) - { - log_msg("Failed to parse ELF string table: section %d, index %d\n", - s_idx, idx); - return ""; - } +char *parse_elf_string_table(elf_obj_t *elf, int s_idx, int idx) { + if (elf->bits == 32) { + Elf32_Shdr shdr; - return (char *)(elf->buf + shdr.sh_offset + idx); + if (parse_elf_section(elf, s_idx, &shdr, NULL)) { + log_msg("Failed to parse ELF string table: section %d, index %d\n", + s_idx, idx); + return ""; } - else /* if (elf->bits == 64) */ - { - Elf64_Shdr shdr; - - if (parse_elf_section(elf, s_idx, NULL, &shdr)) - { - log_msg("Failed to parse ELF string table: section %d, index %d\n", - s_idx, idx); - return ""; - } - return (char *)(elf->buf + shdr.sh_offset + idx); + return (char *)(elf->buf + shdr.sh_offset + idx); + } else { /* if (elf->bits == 64) */ + Elf64_Shdr shdr; + + if (parse_elf_section(elf, s_idx, NULL, &shdr)) { + log_msg("Failed to parse ELF string table: section %d, index %d\n", + s_idx, idx); + return ""; } + + return (char *)(elf->buf + shdr.sh_offset + idx); + } } -int parse_elf_symbol(elf_obj_t *elf, unsigned int ofst, Elf32_Sym *sym32, Elf64_Sym *sym64) -{ - if (sym32) - { - COPY_STRUCT(sym32, elf->buf, ofst, elf->sz); - ENDIAN_ASSIGN_IN_PLACE(sym32->st_name); - ENDIAN_ASSIGN_IN_PLACE(sym32->st_value); - ENDIAN_ASSIGN_IN_PLACE(sym32->st_size); - ENDIAN_ASSIGN_IN_PLACE(sym32->st_info); - ENDIAN_ASSIGN_IN_PLACE(sym32->st_other); - ENDIAN_ASSIGN_IN_PLACE(sym32->st_shndx); - } - else /* if (sym64) */ - { - COPY_STRUCT(sym64, elf->buf, ofst, elf->sz); - ENDIAN_ASSIGN_IN_PLACE(sym64->st_name); - ENDIAN_ASSIGN_IN_PLACE(sym64->st_value); - ENDIAN_ASSIGN_IN_PLACE(sym64->st_size); - ENDIAN_ASSIGN_IN_PLACE(sym64->st_info); - ENDIAN_ASSIGN_IN_PLACE(sym64->st_other); - ENDIAN_ASSIGN_IN_PLACE(sym64->st_shndx); - } - return 0; +int parse_elf_symbol(elf_obj_t *elf, unsigned int ofst, Elf32_Sym *sym32, Elf64_Sym *sym64) { + if (sym32) { + COPY_STRUCT(sym32, elf->buf, ofst, elf->sz); + ENDIAN_ASSIGN_IN_PLACE(sym32->st_name); + ENDIAN_ASSIGN_IN_PLACE(sym32->st_value); + ENDIAN_ASSIGN_IN_PLACE(sym32->st_size); + ENDIAN_ASSIGN_IN_PLACE(sym32->st_info); + ENDIAN_ASSIGN_IN_PLACE(sym32->st_other); + ENDIAN_ASSIGN_IN_PLACE(sym32->st_shndx); + } else { /* if (sym64) */ + COPY_STRUCT(sym64, elf->buf, ofst, elf->sz); + ENDIAN_ASSIGN_IN_PLACE(sym64->st_name); + ENDIAN_ASSIGN_IN_PLACE(sym64->st_value); + ENDIAN_ASSIGN_IN_PLACE(sym64->st_size); + ENDIAN_ASSIGN_IN_PLACE(sym64->st_info); + ENDIAN_ASSIGN_IN_PLACE(sym64->st_other); + ENDIAN_ASSIGN_IN_PLACE(sym64->st_shndx); + } + return 0; bail: - return 1; + return 1; } -int parse_elf(uint8_t *buf, size_t sz, output_fmt_t mode) -{ - elf_obj_t elf; - unsigned int ofst; - int i; - Elf32_Off strtab_off32; - Elf64_Off strtab_off64; /* save String Table offset for later use */ +int parse_elf(uint8_t *buf, size_t sz, output_fmt_t mode) { + elf_obj_t elf; + unsigned int ofst; + int i; + Elf32_Off strtab_off32; + Elf64_Off strtab_off64; /* save String Table offset for later use */ - memset(&elf, 0, sizeof(elf)); - elf.buf = buf; - elf.sz = sz; + memset(&elf, 0, sizeof(elf)); + elf.buf = buf; + elf.sz = sz; - /* Parse Header */ - if (parse_elf_header(&elf)) - goto bail; + /* Parse Header */ + if (parse_elf_header(&elf)) + goto bail; - if (elf.bits == 32) - { - Elf32_Shdr shdr; - for (i = 0; i < elf.hdr32.e_shnum; i++) - { - parse_elf_section(&elf, i, &shdr, NULL); - - if (shdr.sh_type == SHT_STRTAB) - { - char strtsb_name[128]; - - strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name)); - - if (!(strcmp(strtsb_name, ".shstrtab"))) - { - /* log_msg("found section: %s\n", strtsb_name); */ - strtab_off32 = shdr.sh_offset; - break; - } - } + if (elf.bits == 32) { + Elf32_Shdr shdr; + for (i = 0; i < elf.hdr32.e_shnum; i++) { + parse_elf_section(&elf, i, &shdr, NULL); + + if (shdr.sh_type == SHT_STRTAB) { + char strtsb_name[128]; + + strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name)); + + if (!(strcmp(strtsb_name, ".shstrtab"))) { + /* log_msg("found section: %s\n", strtsb_name); */ + strtab_off32 = shdr.sh_offset; + break; } + } } - else /* if (elf.bits == 64) */ - { - Elf64_Shdr shdr; - for (i = 0; i < elf.hdr64.e_shnum; i++) - { - parse_elf_section(&elf, i, NULL, &shdr); - - if (shdr.sh_type == SHT_STRTAB) - { - char strtsb_name[128]; - - strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name)); - - if (!(strcmp(strtsb_name, ".shstrtab"))) - { - /* log_msg("found section: %s\n", strtsb_name); */ - strtab_off64 = shdr.sh_offset; - break; - } - } + } else { /* if (elf.bits == 64) */ + Elf64_Shdr shdr; + for (i = 0; i < elf.hdr64.e_shnum; i++) { + parse_elf_section(&elf, i, NULL, &shdr); + + if (shdr.sh_type == SHT_STRTAB) { + char strtsb_name[128]; + + strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name)); + + if (!(strcmp(strtsb_name, ".shstrtab"))) { + /* log_msg("found section: %s\n", strtsb_name); */ + strtab_off64 = shdr.sh_offset; + break; } + } } + } + + /* Parse all Symbol Tables */ + if (elf.bits == 32) { + Elf32_Shdr shdr; + for (i = 0; i < elf.hdr32.e_shnum; i++) { + parse_elf_section(&elf, i, &shdr, NULL); + + if (shdr.sh_type == SHT_SYMTAB) { + for (ofst = shdr.sh_offset; + ofst < shdr.sh_offset + shdr.sh_size; + ofst += shdr.sh_entsize) { + Elf32_Sym sym; + + parse_elf_symbol(&elf, ofst, &sym, NULL); + + /* For all OBJECTS (data objects), extract the value from the + * proper data segment. + */ + /* if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name) + log_msg("found data object %s\n", + parse_elf_string_table(&elf, + shdr.sh_link, + sym.st_name)); + */ + + if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT + && sym.st_size == 4) { + Elf32_Shdr dhdr; + int val = 0; + char section_name[128]; + + parse_elf_section(&elf, sym.st_shndx, &dhdr, NULL); + + /* For explanition - refer to _MSC_VER version of code */ + strcpy(section_name, (char *)(elf.buf + strtab_off32 + dhdr.sh_name)); + /* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type); */ + + if (strcmp(section_name, ".bss")) { + if (sizeof(val) != sym.st_size) { + /* The target value is declared as an int in + * *_asm_*_offsets.c, which is 4 bytes on all + * targets we currently use. Complain loudly if + * this is not true. + */ + log_msg("Symbol size is wrong\n"); + goto bail; + } - /* Parse all Symbol Tables */ - if (elf.bits == 32) - { - Elf32_Shdr shdr; - for (i = 0; i < elf.hdr32.e_shnum; i++) - { - parse_elf_section(&elf, i, &shdr, NULL); - - if (shdr.sh_type == SHT_SYMTAB) - { - for (ofst = shdr.sh_offset; - ofst < shdr.sh_offset + shdr.sh_size; - ofst += shdr.sh_entsize) - { - Elf32_Sym sym; - - parse_elf_symbol(&elf, ofst, &sym, NULL); - - /* For all OBJECTS (data objects), extract the value from the - * proper data segment. - */ - /* if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name) - log_msg("found data object %s\n", - parse_elf_string_table(&elf, - shdr.sh_link, - sym.st_name)); - */ - - if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT - && sym.st_size == 4) - { - Elf32_Shdr dhdr; - int val = 0; - char section_name[128]; - - parse_elf_section(&elf, sym.st_shndx, &dhdr, NULL); - - /* For explanition - refer to _MSC_VER version of code */ - strcpy(section_name, (char *)(elf.buf + strtab_off32 + dhdr.sh_name)); - /* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type); */ - - if (strcmp(section_name, ".bss")) - { - if (sizeof(val) != sym.st_size) - { - /* The target value is declared as an int in - * asm_*_offsets.c, which is 4 bytes on all - * targets we currently use. Complain loudly if - * this is not true. - */ - log_msg("Symbol size is wrong\n"); - goto bail; - } - - memcpy(&val, - elf.buf + dhdr.sh_offset + sym.st_value, - sym.st_size); - } - - if (!elf.le_data) - { - log_msg("Big Endian data not supported yet!\n"); - goto bail; - } - - switch (mode) - { - case OUTPUT_FMT_RVDS: - printf("%-40s EQU %5d\n", - parse_elf_string_table(&elf, - shdr.sh_link, - sym.st_name), - val); - break; - case OUTPUT_FMT_GAS: - printf(".equ %-40s, %5d\n", - parse_elf_string_table(&elf, - shdr.sh_link, - sym.st_name), - val); - break; - default: - printf("%s = %d\n", - parse_elf_string_table(&elf, - shdr.sh_link, - sym.st_name), - val); - } - } - } + memcpy(&val, + elf.buf + dhdr.sh_offset + sym.st_value, + sym.st_size); } + + if (!elf.le_data) { + log_msg("Big Endian data not supported yet!\n"); + goto bail; + } + + switch (mode) { + case OUTPUT_FMT_RVDS: + printf("%-40s EQU %5d\n", + parse_elf_string_table(&elf, + shdr.sh_link, + sym.st_name), + val); + break; + case OUTPUT_FMT_GAS: + printf(".equ %-40s, %5d\n", + parse_elf_string_table(&elf, + shdr.sh_link, + sym.st_name), + val); + break; + default: + printf("%s = %d\n", + parse_elf_string_table(&elf, + shdr.sh_link, + sym.st_name), + val); + } + } } + } } - else /* if (elf.bits == 64) */ - { - Elf64_Shdr shdr; - for (i = 0; i < elf.hdr64.e_shnum; i++) - { - parse_elf_section(&elf, i, NULL, &shdr); - - if (shdr.sh_type == SHT_SYMTAB) - { - for (ofst = shdr.sh_offset; - ofst < shdr.sh_offset + shdr.sh_size; - ofst += shdr.sh_entsize) - { - Elf64_Sym sym; - - parse_elf_symbol(&elf, ofst, NULL, &sym); - - /* For all OBJECTS (data objects), extract the value from the - * proper data segment. - */ - /* if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name) - log_msg("found data object %s\n", - parse_elf_string_table(&elf, - shdr.sh_link, - sym.st_name)); - */ - - if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT - && sym.st_size == 4) - { - Elf64_Shdr dhdr; - int val = 0; - char section_name[128]; - - parse_elf_section(&elf, sym.st_shndx, NULL, &dhdr); - - /* For explanition - refer to _MSC_VER version of code */ - strcpy(section_name, (char *)(elf.buf + strtab_off64 + dhdr.sh_name)); - /* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type); */ - - if ((strcmp(section_name, ".bss"))) - { - if (sizeof(val) != sym.st_size) - { - /* The target value is declared as an int in - * asm_*_offsets.c, which is 4 bytes on all - * targets we currently use. Complain loudly if - * this is not true. - */ - log_msg("Symbol size is wrong\n"); - goto bail; - } - - memcpy(&val, - elf.buf + dhdr.sh_offset + sym.st_value, - sym.st_size); - } - - if (!elf.le_data) - { - log_msg("Big Endian data not supported yet!\n"); - goto bail; - } - - switch (mode) - { - case OUTPUT_FMT_RVDS: - printf("%-40s EQU %5d\n", - parse_elf_string_table(&elf, - shdr.sh_link, - sym.st_name), - val); - break; - case OUTPUT_FMT_GAS: - printf(".equ %-40s, %5d\n", - parse_elf_string_table(&elf, - shdr.sh_link, - sym.st_name), - val); - break; - default: - printf("%s = %d\n", - parse_elf_string_table(&elf, - shdr.sh_link, - sym.st_name), - val); - } - } - } + } else { /* if (elf.bits == 64) */ + Elf64_Shdr shdr; + for (i = 0; i < elf.hdr64.e_shnum; i++) { + parse_elf_section(&elf, i, NULL, &shdr); + + if (shdr.sh_type == SHT_SYMTAB) { + for (ofst = shdr.sh_offset; + ofst < shdr.sh_offset + shdr.sh_size; + ofst += shdr.sh_entsize) { + Elf64_Sym sym; + + parse_elf_symbol(&elf, ofst, NULL, &sym); + + /* For all OBJECTS (data objects), extract the value from the + * proper data segment. + */ + /* if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name) + log_msg("found data object %s\n", + parse_elf_string_table(&elf, + shdr.sh_link, + sym.st_name)); + */ + + if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT + && sym.st_size == 4) { + Elf64_Shdr dhdr; + int val = 0; + char section_name[128]; + + parse_elf_section(&elf, sym.st_shndx, NULL, &dhdr); + + /* For explanition - refer to _MSC_VER version of code */ + strcpy(section_name, (char *)(elf.buf + strtab_off64 + dhdr.sh_name)); + /* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type); */ + + if ((strcmp(section_name, ".bss"))) { + if (sizeof(val) != sym.st_size) { + /* The target value is declared as an int in + * *_asm_*_offsets.c, which is 4 bytes on all + * targets we currently use. Complain loudly if + * this is not true. + */ + log_msg("Symbol size is wrong\n"); + goto bail; + } + + memcpy(&val, + elf.buf + dhdr.sh_offset + sym.st_value, + sym.st_size); + } + + if (!elf.le_data) { + log_msg("Big Endian data not supported yet!\n"); + goto bail; + } + + switch (mode) { + case OUTPUT_FMT_RVDS: + printf("%-40s EQU %5d\n", + parse_elf_string_table(&elf, + shdr.sh_link, + sym.st_name), + val); + break; + case OUTPUT_FMT_GAS: + printf(".equ %-40s, %5d\n", + parse_elf_string_table(&elf, + shdr.sh_link, + sym.st_name), + val); + break; + default: + printf("%s = %d\n", + parse_elf_string_table(&elf, + shdr.sh_link, + sym.st_name), + val); } + } } + } } + } - if (mode == OUTPUT_FMT_RVDS) - printf(" END\n"); + if (mode == OUTPUT_FMT_RVDS) + printf(" END\n"); - return 0; + return 0; bail: - log_msg("Parse error: File does not appear to be valid ELF32 or ELF64\n"); - return 1; + log_msg("Parse error: File does not appear to be valid ELF32 or ELF64\n"); + return 1; } #endif @@ -671,244 +606,222 @@ bail: #define get_le32(x) ((*(x)) | (*(x+1)) << 8 |(*(x+2)) << 16 | (*(x+3)) << 24 ) #define get_le16(x) ((*(x)) | (*(x+1)) << 8) -int parse_coff(uint8_t *buf, size_t sz) -{ - unsigned int nsections, symtab_ptr, symtab_sz, strtab_ptr; - unsigned int sectionrawdata_ptr; - unsigned int i; - uint8_t *ptr; - uint32_t symoffset; - - char **sectionlist; //this array holds all section names in their correct order. - //it is used to check if the symbol is in .bss or .rdata section. - - nsections = get_le16(buf + 2); - symtab_ptr = get_le32(buf + 8); - symtab_sz = get_le32(buf + 12); - strtab_ptr = symtab_ptr + symtab_sz * 18; - - if (nsections > 96) - { - log_msg("Too many sections\n"); - return 1; - } +int parse_coff(uint8_t *buf, size_t sz) { + unsigned int nsections, symtab_ptr, symtab_sz, strtab_ptr; + unsigned int sectionrawdata_ptr; + unsigned int i; + uint8_t *ptr; + uint32_t symoffset; - sectionlist = malloc(nsections * sizeof(sectionlist)); + char **sectionlist; // this array holds all section names in their correct order. + // it is used to check if the symbol is in .bss or .rdata section. - if (sectionlist == NULL) - { - log_msg("Allocating first level of section list failed\n"); - return 1; - } - - //log_msg("COFF: Found %u symbols in %u sections.\n", symtab_sz, nsections); + nsections = get_le16(buf + 2); + symtab_ptr = get_le32(buf + 8); + symtab_sz = get_le32(buf + 12); + strtab_ptr = symtab_ptr + symtab_sz * 18; - /* - The size of optional header is always zero for an obj file. So, the section header - follows the file header immediately. - */ + if (nsections > 96) { + log_msg("Too many sections\n"); + return 1; + } - ptr = buf + 20; //section header + sectionlist = malloc(nsections * sizeof(sectionlist)); - for (i = 0; i < nsections; i++) - { - char sectionname[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; - strncpy(sectionname, ptr, 8); - //log_msg("COFF: Parsing section %s\n",sectionname); + if (sectionlist == NULL) { + log_msg("Allocating first level of section list failed\n"); + return 1; + } - sectionlist[i] = malloc(strlen(sectionname) + 1); + // log_msg("COFF: Found %u symbols in %u sections.\n", symtab_sz, nsections); - if (sectionlist[i] == NULL) - { - log_msg("Allocating storage for %s failed\n", sectionname); - goto bail; - } - strcpy(sectionlist[i], sectionname); + /* + The size of optional header is always zero for an obj file. So, the section header + follows the file header immediately. + */ - if (!strcmp(sectionname, ".rdata")) sectionrawdata_ptr = get_le32(ptr + 20); + ptr = buf + 20; // section header - ptr += 40; - } + for (i = 0; i < nsections; i++) { + char sectionname[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + strncpy(sectionname, ptr, 8); + // log_msg("COFF: Parsing section %s\n",sectionname); - //log_msg("COFF: Symbol table at offset %u\n", symtab_ptr); - //log_msg("COFF: raw data pointer ofset for section .rdata is %u\n", sectionrawdata_ptr); - - /* The compiler puts the data with non-zero offset in .rdata section, but puts the data with - zero offset in .bss section. So, if the data in in .bss section, set offset=0. - Note from Wiki: In an object module compiled from C, the bss section contains - the local variables (but not functions) that were declared with the static keyword, - except for those with non-zero initial values. (In C, static variables are initialized - to zero by default.) It also contains the non-local (both extern and static) variables - that are also initialized to zero (either explicitly or by default). - */ - //move to symbol table - /* COFF symbol table: - offset field - 0 Name(*) - 8 Value - 12 SectionNumber - 14 Type - 16 StorageClass - 17 NumberOfAuxSymbols - */ - ptr = buf + symtab_ptr; - - for (i = 0; i < symtab_sz; i++) - { - int16_t section = get_le16(ptr + 12); //section number - - if (section > 0 && ptr[16] == 2) - { - //if(section > 0 && ptr[16] == 3 && get_le32(ptr+8)) { - - if (get_le32(ptr)) - { - char name[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; - strncpy(name, ptr, 8); - //log_msg("COFF: Parsing symbol %s\n",name); - /* The 64bit Windows compiler doesn't prefix with an _. - * Check what's there, and bump if necessary - */ - if (name[0] == '_') - printf("%-40s EQU ", name + 1); - else - printf("%-40s EQU ", name); - } - else - { - //log_msg("COFF: Parsing symbol %s\n", - // buf + strtab_ptr + get_le32(ptr+4)); - if ((buf + strtab_ptr + get_le32(ptr + 4))[0] == '_') - printf("%-40s EQU ", - buf + strtab_ptr + get_le32(ptr + 4) + 1); - else - printf("%-40s EQU ", buf + strtab_ptr + get_le32(ptr + 4)); - } + sectionlist[i] = malloc(strlen(sectionname) + 1); - if (!(strcmp(sectionlist[section-1], ".bss"))) - { - symoffset = 0; - } - else - { - symoffset = get_le32(buf + sectionrawdata_ptr + get_le32(ptr + 8)); - } + if (sectionlist[i] == NULL) { + log_msg("Allocating storage for %s failed\n", sectionname); + goto bail; + } + strcpy(sectionlist[i], sectionname); + + if (!strcmp(sectionname, ".rdata")) sectionrawdata_ptr = get_le32(ptr + 20); + + ptr += 40; + } + + // log_msg("COFF: Symbol table at offset %u\n", symtab_ptr); + // log_msg("COFF: raw data pointer ofset for section .rdata is %u\n", sectionrawdata_ptr); + + /* The compiler puts the data with non-zero offset in .rdata section, but puts the data with + zero offset in .bss section. So, if the data in in .bss section, set offset=0. + Note from Wiki: In an object module compiled from C, the bss section contains + the local variables (but not functions) that were declared with the static keyword, + except for those with non-zero initial values. (In C, static variables are initialized + to zero by default.) It also contains the non-local (both extern and static) variables + that are also initialized to zero (either explicitly or by default). + */ + // move to symbol table + /* COFF symbol table: + offset field + 0 Name(*) + 8 Value + 12 SectionNumber + 14 Type + 16 StorageClass + 17 NumberOfAuxSymbols + */ + ptr = buf + symtab_ptr; + + for (i = 0; i < symtab_sz; i++) { + int16_t section = get_le16(ptr + 12); // section number + + if (section > 0 && ptr[16] == 2) { + // if(section > 0 && ptr[16] == 3 && get_le32(ptr+8)) { + + if (get_le32(ptr)) { + char name[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + strncpy(name, ptr, 8); + // log_msg("COFF: Parsing symbol %s\n",name); + /* The 64bit Windows compiler doesn't prefix with an _. + * Check what's there, and bump if necessary + */ + if (name[0] == '_') + printf("%-40s EQU ", name + 1); + else + printf("%-40s EQU ", name); + } else { + // log_msg("COFF: Parsing symbol %s\n", + // buf + strtab_ptr + get_le32(ptr+4)); + if ((buf + strtab_ptr + get_le32(ptr + 4))[0] == '_') + printf("%-40s EQU ", + buf + strtab_ptr + get_le32(ptr + 4) + 1); + else + printf("%-40s EQU ", buf + strtab_ptr + get_le32(ptr + 4)); + } - //log_msg(" Section: %d\n",section); - //log_msg(" Class: %d\n",ptr[16]); - //log_msg(" Address: %u\n",get_le32(ptr+8)); - //log_msg(" Offset: %u\n", symoffset); + if (!(strcmp(sectionlist[section - 1], ".bss"))) { + symoffset = 0; + } else { + symoffset = get_le32(buf + sectionrawdata_ptr + get_le32(ptr + 8)); + } - printf("%5d\n", symoffset); - } + // log_msg(" Section: %d\n",section); + // log_msg(" Class: %d\n",ptr[16]); + // log_msg(" Address: %u\n",get_le32(ptr+8)); + // log_msg(" Offset: %u\n", symoffset); - ptr += 18; + printf("%5d\n", symoffset); } - printf(" END\n"); + ptr += 18; + } - for (i = 0; i < nsections; i++) - { - free(sectionlist[i]); - } + printf(" END\n"); - free(sectionlist); + for (i = 0; i < nsections; i++) { + free(sectionlist[i]); + } - return 0; + free(sectionlist); + + return 0; bail: - for (i = 0; i < nsections; i++) - { - free(sectionlist[i]); - } + for (i = 0; i < nsections; i++) { + free(sectionlist[i]); + } - free(sectionlist); + free(sectionlist); - return 1; + return 1; } #endif /* defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) */ -int main(int argc, char **argv) -{ - output_fmt_t mode = OUTPUT_FMT_PLAIN; - const char *f; - uint8_t *file_buf; - int res; - FILE *fp; - long int file_size; - - if (argc < 2 || argc > 3) - { - fprintf(stderr, "Usage: %s [output format] <obj file>\n\n", argv[0]); - fprintf(stderr, " <obj file>\tobject file to parse\n"); - fprintf(stderr, "Output Formats:\n"); - fprintf(stderr, " gas - compatible with GNU assembler\n"); - fprintf(stderr, " rvds - compatible with armasm\n"); - goto bail; - } - - f = argv[2]; - - if (!strcmp(argv[1], "rvds")) - mode = OUTPUT_FMT_RVDS; - else if (!strcmp(argv[1], "gas")) - mode = OUTPUT_FMT_GAS; - else - f = argv[1]; - - fp = fopen(f, "rb"); - - if (!fp) - { - perror("Unable to open file"); - goto bail; - } - - if (fseek(fp, 0, SEEK_END)) - { - perror("stat"); - goto bail; - } - - file_size = ftell(fp); - file_buf = malloc(file_size); - - if (!file_buf) - { - perror("malloc"); - goto bail; - } - - rewind(fp); - - if (fread(file_buf, sizeof(char), file_size, fp) != file_size) - { - perror("read"); - goto bail; - } - - if (fclose(fp)) - { - perror("close"); - goto bail; - } +int main(int argc, char **argv) { + output_fmt_t mode = OUTPUT_FMT_PLAIN; + const char *f; + uint8_t *file_buf; + int res; + FILE *fp; + long int file_size; + + if (argc < 2 || argc > 3) { + fprintf(stderr, "Usage: %s [output format] <obj file>\n\n", argv[0]); + fprintf(stderr, " <obj file>\tobject file to parse\n"); + fprintf(stderr, "Output Formats:\n"); + fprintf(stderr, " gas - compatible with GNU assembler\n"); + fprintf(stderr, " rvds - compatible with armasm\n"); + goto bail; + } + + f = argv[2]; + + if (!strcmp(argv[1], "rvds")) + mode = OUTPUT_FMT_RVDS; + else if (!strcmp(argv[1], "gas")) + mode = OUTPUT_FMT_GAS; + else + f = argv[1]; + + fp = fopen(f, "rb"); + + if (!fp) { + perror("Unable to open file"); + goto bail; + } + + if (fseek(fp, 0, SEEK_END)) { + perror("stat"); + goto bail; + } + + file_size = ftell(fp); + file_buf = malloc(file_size); + + if (!file_buf) { + perror("malloc"); + goto bail; + } + + rewind(fp); + + if (fread(file_buf, sizeof(char), file_size, fp) != file_size) { + perror("read"); + goto bail; + } + + if (fclose(fp)) { + perror("close"); + goto bail; + } #if defined(__GNUC__) && __GNUC__ #if defined(__MACH__) - res = parse_macho(file_buf, file_size); + res = parse_macho(file_buf, file_size, mode); #elif defined(__ELF__) - res = parse_elf(file_buf, file_size, mode); + res = parse_elf(file_buf, file_size, mode); #endif #endif #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) - res = parse_coff(file_buf, file_size); + res = parse_coff(file_buf, file_size); #endif - free(file_buf); + free(file_buf); - if (!res) - return EXIT_SUCCESS; + if (!res) + return EXIT_SUCCESS; bail: - return EXIT_FAILURE; + return EXIT_FAILURE; } diff --git a/build/make/rtcd.sh b/build/make/rtcd.sh index ddf9e09a4..2967b5aed 100755 --- a/build/make/rtcd.sh +++ b/build/make/rtcd.sh @@ -59,13 +59,13 @@ for f in $defs_file; do [ -f "$f" ] || usage; done # Routines for the RTCD DSL to call # prototype() { - local rtyp + rtyp="" case "$1" in unsigned) rtyp="$1 "; shift;; esac rtyp="${rtyp}$1" - local fn="$2" - local args="$3" + fn="$2" + args="$3" eval "${2}_rtyp='$rtyp'" eval "${2}_args='$3'" @@ -74,7 +74,7 @@ prototype() { } specialize() { - local fn="$1" + fn="$1" shift for opt in "$@"; do eval "${fn}_${opt}=${fn}_${opt}" @@ -84,13 +84,13 @@ specialize() { require() { for fn in $ALL_FUNCS; do for opt in "$@"; do - local ofn=$(eval "echo \$${fn}_${opt}") + ofn=$(eval "echo \$${fn}_${opt}") [ -z "$ofn" ] && continue # if we already have a default, then we can disable it, as we know # we can do better. - local best=$(eval "echo \$${fn}_default") - local best_ofn=$(eval "echo \$${best}") + best=$(eval "echo \$${fn}_default") + best_ofn=$(eval "echo \$${best}") [ -n "$best" ] && [ "$best_ofn" != "$ofn" ] && eval "${best}_link=false" eval "${fn}_default=${fn}_${opt}" eval "${fn}_${opt}_link=true" @@ -121,15 +121,15 @@ process_forward_decls() { determine_indirection() { [ "$CONFIG_RUNTIME_CPU_DETECT" = "yes" ] || require $ALL_ARCHS for fn in $ALL_FUNCS; do - local n="" - local rtyp="$(eval "echo \$${fn}_rtyp")" - local args="$(eval "echo \"\$${fn}_args\"")" - local dfn="$(eval "echo \$${fn}_default")" + n="" + rtyp="$(eval "echo \$${fn}_rtyp")" + args="$(eval "echo \"\$${fn}_args\"")" + dfn="$(eval "echo \$${fn}_default")" dfn=$(eval "echo \$${dfn}") for opt in "$@"; do - local ofn=$(eval "echo \$${fn}_${opt}") + ofn=$(eval "echo \$${fn}_${opt}") [ -z "$ofn" ] && continue - local link=$(eval "echo \$${fn}_${opt}_link") + link=$(eval "echo \$${fn}_${opt}_link") [ "$link" = "false" ] && continue n="${n}x" done @@ -143,12 +143,12 @@ determine_indirection() { declare_function_pointers() { for fn in $ALL_FUNCS; do - local rtyp="$(eval "echo \$${fn}_rtyp")" - local args="$(eval "echo \"\$${fn}_args\"")" - local dfn="$(eval "echo \$${fn}_default")" + rtyp="$(eval "echo \$${fn}_rtyp")" + args="$(eval "echo \"\$${fn}_args\"")" + dfn="$(eval "echo \$${fn}_default")" dfn=$(eval "echo \$${dfn}") for opt in "$@"; do - local ofn=$(eval "echo \$${fn}_${opt}") + ofn=$(eval "echo \$${fn}_${opt}") [ -z "$ofn" ] && continue echo "$rtyp ${ofn}($args);" done @@ -163,20 +163,20 @@ declare_function_pointers() { set_function_pointers() { for fn in $ALL_FUNCS; do - local n="" - local rtyp="$(eval "echo \$${fn}_rtyp")" - local args="$(eval "echo \"\$${fn}_args\"")" - local dfn="$(eval "echo \$${fn}_default")" + n="" + rtyp="$(eval "echo \$${fn}_rtyp")" + args="$(eval "echo \"\$${fn}_args\"")" + dfn="$(eval "echo \$${fn}_default")" dfn=$(eval "echo \$${dfn}") if $(eval "echo \$${fn}_indirect"); then echo " $fn = $dfn;" for opt in "$@"; do - local ofn=$(eval "echo \$${fn}_${opt}") + ofn=$(eval "echo \$${fn}_${opt}") [ -z "$ofn" ] && continue [ "$ofn" = "$dfn" ] && continue; - local link=$(eval "echo \$${fn}_${opt}_link") + link=$(eval "echo \$${fn}_${opt}_link") [ "$link" = "false" ] && continue - local cond="$(eval "echo \$have_${opt}")" + cond="$(eval "echo \$have_${opt}")" echo " if (${cond}) $fn = $ofn;" done fi @@ -185,7 +185,7 @@ set_function_pointers() { } filter() { - local filtered + filtered="" for opt in "$@"; do [ -z $(eval "echo \$disable_${opt}") ] && filtered="$filtered $opt" done @@ -196,8 +196,9 @@ filter() { # Helper functions for generating the arch specific RTCD files # common_top() { - local outfile_basename=$(basename ${symbol:-rtcd.h}) - local include_guard=$(echo $outfile_basename | tr '[a-z]' '[A-Z]' | tr -c '[A-Z]' _) + outfile_basename=$(basename ${symbol:-rtcd}) + include_guard=$(echo $outfile_basename | tr '[a-z]' '[A-Z]' | \ + tr -c '[A-Z0-9]' _)H_ cat <<EOF #ifndef ${include_guard} #define ${include_guard} @@ -227,7 +228,7 @@ x86() { # Assign the helper variable for each enabled extension for opt in $ALL_ARCHS; do - local uc=$(echo $opt | tr '[a-z]' '[A-Z]') + uc=$(echo $opt | tr '[a-z]' '[A-Z]') eval "have_${opt}=\"flags & HAS_${uc}\"" done @@ -254,7 +255,7 @@ arm() { # Assign the helper variable for each enabled extension for opt in $ALL_ARCHS; do - local uc=$(echo $opt | tr '[a-z]' '[A-Z]') + uc=$(echo $opt | tr '[a-z]' '[A-Z]') eval "have_${opt}=\"flags & HAS_${uc}\"" done @@ -289,9 +290,15 @@ static void setup_rtcd_internal(void) { $(set_function_pointers c $ALL_ARCHS) #if HAVE_DSPR2 +#if CONFIG_VP8 void dsputil_static_init(); dsputil_static_init(); #endif +#if CONFIG_VP9 +void vp9_dsputil_static_init(); +vp9_dsputil_static_init(); +#endif +#endif } #endif $(common_bottom) @@ -320,11 +327,11 @@ EOF require c case $arch in x86) - ALL_ARCHS=$(filter mmx sse sse2 sse3 ssse3 sse4_1) + ALL_ARCHS=$(filter mmx sse sse2 sse3 ssse3 sse4_1 avx avx2) x86 ;; x86_64) - ALL_ARCHS=$(filter mmx sse sse2 sse3 ssse3 sse4_1) + ALL_ARCHS=$(filter mmx sse sse2 sse3 ssse3 sse4_1 avx avx2) REQUIRES=${REQUIRES:-mmx sse sse2} require $(filter $REQUIRES) x86 diff --git a/build/make/thumb.pm b/build/make/thumb.pm new file mode 100644 index 000000000..e1f34c1ec --- /dev/null +++ b/build/make/thumb.pm @@ -0,0 +1,70 @@ +#!/usr/bin/perl +## +## Copyright (c) 2013 The WebM project authors. All Rights Reserved. +## +## Use of this source code is governed by a BSD-style license +## that can be found in the LICENSE file in the root of the source +## tree. An additional intellectual property rights grant can be found +## in the file PATENTS. All contributing project authors may +## be found in the AUTHORS file in the root of the source tree. +## + +package thumb; + +sub FixThumbInstructions($$) +{ + my $short_branches = $_[1]; + my $branch_shift_offset = $short_branches ? 1 : 0; + + # Write additions with shifts, such as "add r10, r11, lsl #8", + # in three operand form, "add r10, r10, r11, lsl #8". + s/(add\s+)(r\d+),\s*(r\d+),\s*(lsl #\d+)/$1$2, $2, $3, $4/g; + + # Convert additions with a non-constant shift into a sequence + # with left shift, addition and a right shift (to restore the + # register to the original value). Currently the right shift + # isn't necessary in the code base since the values in these + # registers aren't used, but doing the shift for consitency. + # This converts instructions such as "add r12, r12, r5, lsl r4" + # into the sequence "lsl r5, r4", "add r12, r12, r5", "lsr r5, r4". + s/^(\s*)(add)(\s+)(r\d+),\s*(r\d+),\s*(r\d+),\s*lsl (r\d+)/$1lsl$3$6, $7\n$1$2$3$4, $5, $6\n$1lsr$3$6, $7/g; + + # Convert loads with right shifts in the indexing into a + # sequence of an add, load and sub. This converts + # "ldrb r4, [r9, lr, asr #1]" into "add r9, r9, lr, asr #1", + # "ldrb r9, [r9]", "sub r9, r9, lr, asr #1". + s/^(\s*)(ldrb)(\s+)(r\d+),\s*\[(\w+),\s*(\w+),\s*(asr #\d+)\]/$1add $3$5, $5, $6, $7\n$1$2$3$4, [$5]\n$1sub $3$5, $5, $6, $7/g; + + # Convert register indexing with writeback into a separate add + # instruction. This converts "ldrb r12, [r1, r2]!" into + # "ldrb r12, [r1, r2]", "add r1, r1, r2". + s/^(\s*)(ldrb)(\s+)(r\d+),\s*\[(\w+),\s*(\w+)\]!/$1$2$3$4, [$5, $6]\n$1add $3$5, $6/g; + + # Convert negative register indexing into separate sub/add instructions. + # This converts "ldrne r4, [src, -pstep, lsl #1]" into + # "subne src, src, pstep, lsl #1", "ldrne r4, [src]", + # "addne src, src, pstep, lsl #1". In a couple of cases where + # this is used, it's used for two subsequent load instructions, + # where a hand-written version of it could merge two subsequent + # add and sub instructions. + s/^(\s*)((ldr|str|pld)(ne)?)(\s+)(r\d+,\s*)?\[(\w+), -([^\]]+)\]/$1sub$4$5$7, $7, $8\n$1$2$5$6\[$7\]\n$1add$4$5$7, $7, $8/g; + + # Convert register post indexing to a separate add instruction. + # This converts "ldrneb r9, [r0], r2" into "ldrneb r9, [r0]", + # "add r0, r2". + s/^(\s*)((ldr|str)(ne)?[bhd]?)(\s+)(\w+),(\s*\w+,)?\s*\[(\w+)\],\s*(\w+)/$1$2$5$6,$7 [$8]\n$1add$4$5$8, $8, $9/g; + + # Convert a conditional addition to the pc register into a series of + # instructions. This converts "addlt pc, pc, r3, lsl #2" into + # "itttt lt", "movlt.n r12, pc", "addlt.w r12, #12", + # "addlt.w r12, r12, r3, lsl #2", "movlt.n pc, r12". + # This assumes that r12 is free at this point. + s/^(\s*)addlt(\s+)pc,\s*pc,\s*(\w+),\s*lsl\s*#(\d+)/$1itttt$2lt\n$1movlt.n$2r12, pc\n$1addlt.w$2r12, #12\n$1addlt.w$2r12, r12, $3, lsl #($4-$branch_shift_offset)\n$1movlt.n$2pc, r12/g; + + # Convert "mov pc, lr" into "bx lr", since the former only works + # for switching from arm to thumb (and only in armv7), but not + # from thumb to arm. + s/mov(\s*)pc\s*,\s*lr/bx$1lr/g; +} + +1; diff --git a/build/make/version.sh b/build/make/version.sh index 3efb956bb..e31e568aa 100755 --- a/build/make/version.sh +++ b/build/make/version.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh ## ## Copyright (c) 2010 The WebM project authors. All Rights Reserved. ## diff --git a/build/x86-msvs/obj_int_extract.bat b/build/x86-msvs/obj_int_extract.bat index 1bb865331..4e9b0ecd0 100644 --- a/build/x86-msvs/obj_int_extract.bat +++ b/build/x86-msvs/obj_int_extract.bat @@ -7,9 +7,6 @@ REM in the file PATENTS. All contributing project authors may REM be found in the AUTHORS file in the root of the source tree. echo on -cl /I "./" /I "%1" /nologo /c "%1/vp8/common/asm_com_offsets.c" -cl /I "./" /I "%1" /nologo /c "%1/vp8/decoder/asm_dec_offsets.c" -cl /I "./" /I "%1" /nologo /c "%1/vp8/encoder/asm_enc_offsets.c" -obj_int_extract.exe rvds "asm_com_offsets.obj" > "asm_com_offsets.asm" -obj_int_extract.exe rvds "asm_dec_offsets.obj" > "asm_dec_offsets.asm" -obj_int_extract.exe rvds "asm_enc_offsets.obj" > "asm_enc_offsets.asm" +cl /I "./" /I "%1" /nologo /c "%1/vp8/encoder/vp8_asm_enc_offsets.c" +obj_int_extract.exe rvds "vp8_asm_enc_offsets.obj" > "vp8_asm_enc_offsets.asm" + diff --git a/build/x86-msvs/yasm.rules b/build/x86-msvs/yasm.rules deleted file mode 100644 index ee1fefbca..000000000 --- a/build/x86-msvs/yasm.rules +++ /dev/null @@ -1,115 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<VisualStudioToolFile
- Name="Yasm"
- Version="8.00"
- >
- <Rules>
- <CustomBuildRule
- Name="YASM"
- DisplayName="Yasm Assembler"
- CommandLine="yasm -Xvc -f $(PlatformName) [AllOptions] [AdditionalOptions] [Inputs]"
- Outputs="[$ObjectFileName]"
- FileExtensions="*.asm"
- ExecutionDescription="Assembling $(InputFileName)"
- ShowOnlyRuleProperties="false"
- >
- <Properties>
- <StringProperty
- Name="Defines"
- DisplayName="Definitions"
- Category="Pre-Defined Symbols"
- Description="Specify pre-defined symbols ('symbol' or 'symbol = value') "
- Switch="-D [value]"
- Delimited="true"
- Inheritable="true"
- />
- <StringProperty
- Name="IncludePaths"
- DisplayName="Include Paths"
- Category="Configuration"
- Description="Set the paths for any additional include files"
- Switch="-I [value]"
- Delimited="true"
- Inheritable="true"
- />
- <StringProperty
- Name="UnDefines"
- DisplayName="Remove Definitions"
- Category="Pre-Defined Symbols"
- Description="Remove pre-defined symbols "
- Switch="-U [value]"
- Delimited="true"
- Inheritable="true"
- />
- <StringProperty
- Name="ObjectFileName"
- DisplayName="Object File Name"
- Category="Output"
- Description="Select the output file name"
- Switch="-o [value]"
- DefaultValue="$(IntDir)\$(InputName).obj"
- />
- <StringProperty
- Name="ListFileName"
- DisplayName="List File Name"
- Category="Output"
- Description="Select an output listing by setting its file name"
- Switch="-l [value]"
- />
- <StringProperty
- Name="PreIncludeFile"
- DisplayName="Pre Include File"
- Category="Configuration"
- Description="Select a pre-included file by setting its name"
- Switch="-P [value]"
- />
- <BooleanProperty
- Name="Debug"
- DisplayName="Debug Information"
- Category="Output"
- Description="Generate debugging information"
- Switch="-g cv8"
- />
- <EnumProperty
- Name="PreProc"
- DisplayName="Pre-Processor"
- Category="Configuration"
- Description="Select the pre-processor ('nasm' or 'raw')"
- >
- <Values>
- <EnumValue
- Value="0"
- Switch="-rnasm"
- DisplayName="Nasm "
- />
- <EnumValue
- Value="1"
- Switch="-rraw"
- DisplayName="Raw"
- />
- </Values>
- </EnumProperty>
- <EnumProperty
- Name="Parser"
- DisplayName="Parser"
- Category="Configuration"
- Description="Select the parser for Intel ('nasm') or AT&T ( 'gas') syntax"
- >
- <Values>
- <EnumValue
- Value="0"
- Switch="-pnasm"
- DisplayName="Nasm"
- />
- <EnumValue
- Value="1"
- Switch="-pgas"
- DisplayName="Gas"
- />
- </Values>
- </EnumProperty>
- </Properties>
- </CustomBuildRule>
- </Rules>
-</VisualStudioToolFile>
-
|