1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-22 21:23:07 +03:00
esp8266/tools/sdk/lib/fix_sdk_libs.sh
M Hightower 4a0b66b017
Heap addendum to handle changes in NON-OS SDK 3.0.x (#8746)
## WPA2 Enterprise connections
References - merged PRs:
* https://github.com/esp8266/Arduino/pull/8529
* https://github.com/esp8266/Arduino/pull/8566 - these occurred with connect/disconnect with WPA-Enterprise
* https://github.com/esp8266/Arduino/pull/8736#issue-1470774550

The NON-OS SDK 3.0.x has breaking changes to the [`pvPortMalloc`](bf890b22e5/include/mem.h (L42)) function. They added a new `bool` argument for selecting a heap. 
```cpp
void *pvPortMalloc (size_t sz, const char *, unsigned, bool);
```

To avoid breaking the build, I added a new thin wrapper function `sdk3_pvPortMalloc` to `heap.cpp`. 
Edited new SDK LIBs to call `pvPortMalloc`'s replacement `sdk3_pvPortMalloc`.

They also added `pvPortZallocIram` and `pvPortCallocIram`, which are not a problem to support. Support added to `heap.cpp`.

Issues with WPA2 Enterprise in new SDKs:
* v3.0.0 and v3.0.1 - have the same memory leak and duplicate free bugs from before
* v3.0.2 through v3.0.5 - have the same memory leak; however, _no_ duplicate free crash.
* memory leak can be seen by cycling through setup, connect, disconnect, and clear setup - repeatedly.

Updated `wpa2_eap_patch.cpp` and binary patch scripts to handle v3.0.0 through v3.0.5.
Patched SDKs v3.0.0 through v3.0.5

## Duplicate Non-32-bit exception handler
Issue: At v3.0.0 and above `libmain.a` supplies a built-in exception handler (`load_non_32_wide_handler`) for non-32-bit access. Our non-32-bit access handler (`non32xfer_exception_handler`) overrides it. 

Solution: Add "weak" attribute to symbol `load_non_32_wide_handler`. Adjust the build to default to the SDK's built-in non-32-bit handler.  If there is a need to use our non-32-bit handler, make the selection from the Arduino IDE Tools menu `Non-32-Bit Access: "Byte/Word access to IRAM/PROGMEM (very slow)"`.

With SDKs v3.0.0 and above a "non-32-bit exception handler" is always present.
2022-12-16 11:11:19 +03:00

178 lines
6.9 KiB
Bash
Executable File

#!/bin/bash
set -e
add_path_ifexist() {
if [[ -d $1 ]]; then
export PATH=$( realpath $1 ):$PATH
return 0
fi
return 1
}
if ! which xtensa-lx106-elf-ar | grep "tools/xtensa-lx106-elf/bin" >>/dev/null; then
add_path_ifexist "../../../xtensa-lx106-elf/bin" || add_path_ifexist "../../xtensa-lx106-elf/bin"
fi
WORK_SPACE=${PWD}
VERSION=$(basename ${PWD})
addSymbol_system_func1() {
if ! xtensa-lx106-elf-nm user_interface.o | grep -q " T system_func1"; then # Don't add symbol if it already exists
ADDRESS=$1
xtensa-lx106-elf-objcopy --add-symbol system_func1=.irom0.text:${ADDRESS},function,global user_interface.o
fi
}
patchFile() {
FILE=$1
ADDRESS=$2 # DO NOT PASS AS HEX!
LENGTH=$3 # DO NOT PASS AS HEX!
EXPECTED=$4
REPLACEWITH=$5
if [[ "$(dd if=$FILE bs=1 count=$LENGTH skip=$ADDRESS status=none | base64 -w0)" = "$EXPECTED" ]]; then
echo "Patching $VERSION $1 ..."
echo $5 | base64 -d | dd of=$FILE bs=1 count=$LENGTH seek=$ADDRESS conv=notrunc
elif ! [[ "$(dd if=$FILE bs=1 count=$LENGTH skip=$ADDRESS status=none | base64 -w0)" = "$REPLACEWITH" ]]; then
echo "PATCH FAILED!"
echo "dd if=$FILE bs=1 count=$LENGTH skip=$ADDRESS status=none | base64 -w0"
dd if=$FILE bs=1 count=$LENGTH skip=$ADDRESS status=none | hexdump -C
dd if=$FILE bs=1 count=$LENGTH skip=$ADDRESS status=none | base64 -w0
echo ""
exit 1
fi
}
grepPatchFiles() {
local SDKVER OLDNAME NEWNAME FILES OLDNAME64 NEWNAME64 FILE OFFSET PATTERN
SDKVER="${1}"
OLDNAME="${2}"
NEWNAME="${3}"
FILES="${4}"
[[ "${SDKVER:0:9}" != "NONOSDK30" ]] && return
if [[ -z "${FILES}" ]]; then
echo "grepPatchFile: bad input: file specification required"
exit 1
fi
if [[ "${#OLDNAME}" != "${#NEWNAME}" ]]; then
echo "grepPatchFile: bad input: old name ${OLDNAME}(${#OLDNAME}) and new name ${NEWNAME}(${#NEWNAME}) must be the same length."
exit 1
fi
OLDNAME64=( `echo -n "${OLDNAME}" | base64 -w0` )
NEWNAME64=( `echo -n "${NEWNAME}" | base64 -w0` )
while read -u3 FILE OFFSET PATTERN; do
if [[ "${#OLDNAME}" == "${#PATTERN}" ]] && [[ "${OLDNAME}" == "${PATTERN}" ]]; then
patchFile "$FILE" "$OFFSET" "${#PATTERN}" "${OLDNAME64}" "${NEWNAME64}"
else
echo "grepPatchFile: bad parameters FILE=${FILE} OFFSET=${OFFSET} PATTERN=${PATTERN}"
exit 1
fi
done 3< <( grep --with-filename --byte-offset --only-matching --text "${OLDNAME}" $FILES | tr ":" " " )
return
}
redefineSym() {
local SDKVER OLDNAME NEWNAME FILES FILE EXTRA PATTERN
SDKVER="${1}"
OLDNAME="${2}"
NEWNAME="${3}"
FILES="${4}"
[[ "${SDKVER:0:9}" != "NONOSDK30" ]] && return
if [[ -z "${FILES}" ]]; then
echo "redefineSym: bad input: file specification required"
exit 1
fi
PATTERN="UND ${OLDNAME}"
for FILE in $FILES ; do
echo "xtensa-lx106-elf-objcopy --redefine-sym ${OLDNAME}=${NEWNAME} \"$FILE\""
echo "Before:"
xtensa-lx106-elf-nm "$FILE" | grep ${OLDNAME} | sort -u
xtensa-lx106-elf-objcopy --redefine-sym ${OLDNAME}=${NEWNAME} "$FILE"
echo "After:"
xtensa-lx106-elf-nm "$FILE" | grep ${OLDNAME} | sort -u
done
return
}
# # xtensa-lx106-elf-ar x libwpa2.a eap.o
if [[ "--shell" == "$1" ]]; then
# need to poke around a bit
bash --rcfile <(echo ". ~/.bashrc; cd ${WORK_SPACE}")
exit 0
fi
if [[ ! -f libmain.a ]]; then
echo -e "\n\n*** Archive libmain.a is missing ***\n\n"
exit 1
fi
# Remove mem_manager.o from libmain.a to use custom heap implementation,
# and time.o to fix redefinition of time-related functions:
xtensa-lx106-elf-ar d libmain.a mem_manager.o
xtensa-lx106-elf-ar d libmain.a time.o
# Patch WPA2-Enterprise double-free
xtensa-lx106-elf-ar x libwpa2.a eap.o
eapcs=$(sha256sum eap.o | awk '{print $1}')
# Rename `hostname` and `default_hostname` symbols:
xtensa-lx106-elf-ar x libmain.a eagle_lwip_if.o user_interface.o
lwipcs=$(sha256sum eagle_lwip_if.o | awk '{print $1}')
uics=$(sha256sum user_interface.o | awk '{print $1}')
xtensa-lx106-elf-objcopy --redefine-sym hostname=wifi_station_hostname user_interface.o
xtensa-lx106-elf-objcopy --redefine-sym hostname=wifi_station_hostname eagle_lwip_if.o
xtensa-lx106-elf-objcopy --redefine-sym default_hostname=wifi_station_default_hostname user_interface.o
xtensa-lx106-elf-objcopy --redefine-sym default_hostname=wifi_station_default_hostname eagle_lwip_if.o
if [[ ${VERSION} == "NONOSDK221" ]]; then
addSymbol_system_func1 "0x60"
patchFile "eap.o" "3055" "2" "wAA=" "8CA=" # WPA2-Enterprise patch which replaces a double-free with nop, see #8082
patchFile "eap.o" "26352" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK22x"* ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "3059" "2" "wAA=" "8CA=" # WPA2-Enterprise patch which replaces a double-free with nop, see #8082
patchFile "eap.o" "26356" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK3V0" ]]; then
addSymbol_system_func1 "0x60"
patchFile "eap.o" "3059" "2" "wAA=" "8CA=" # WPA2-Enterprise patch which replaces a double-free with nop, see #8082
patchFile "eap.o" "26356" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK300" ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "19204" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK301" ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "26364" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK302" ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "26536" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK303" ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "26536" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK304" ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "19376" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK305" ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "67670" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
else
echo "WARN: Unknown address for system_func1() called by system_restart_local()"
fi
if [[ $(sha256sum eap.o | awk '{print $1}') != $eapcs ]]; then
xtensa-lx106-elf-ar r libwpa2.a eap.o
fi
if [[ $(sha256sum user_interface.o | awk '{print $1}') != $uics || $(sha256sum eagle_lwip_if.o | awk '{print $1}') != $lwipcs ]]; then
xtensa-lx106-elf-ar r libmain.a eagle_lwip_if.o user_interface.o
fi
rm -f eagle_lwip_if.o user_interface.o eap.o
if [[ ${VERSION} == "NONOSDK3V0" ]]; then
xtensa-lx106-elf-objcopy --weaken-symbol load_non_32_wide_handler libmain.a
elif [[ ${VERSION:0:9} == "NONOSDK30" ]]; then
# v3.0.0 and up use a non-standard pvPortMalloc.
# SDK Library global replace
redefineSym "${VERSION}" "pvPortMalloc" "sdk3_pvPortMalloc" '*.a'
xtensa-lx106-elf-objcopy --weaken-symbol load_non_32_wide_handler libmain.a
fi