1#!/bin/bash
2(set -o igncr) 2>/dev/null && set -o igncr; # this comment is required
3set -$-ue${DEBUG+xv}
4
5#######################################################################################################################
6# This script processes the memory consumption of an application and prints it out to the console.
7#
8# usage:
9#	memcalc.bash <READELFFILE> <AVAILABLEFLASH> <AVAILABLESRAM> <STARTFLASH> <STARTSRAM>
10#
11#######################################################################################################################
12
13READELFFILE=$1              # file location of readelf output
14AVAILABLEFLASH=$2           # Max available internal flash
15AVAILABLESRAM=$3            # Max available internal SRAM
16STARTFLASH=$4               # Start of internal flash
17STARTSRAM=$5                # Start of internal SRAM
18
19ENDFLASH=$((STARTFLASH + AVAILABLEFLASH))
20ENDSRAM=$((STARTSRAM + AVAILABLESRAM))
21
22# Gather the numbers
23memcalc() {
24    local internalFlash=0
25    local internalSram=0
26
27    printf "   -------------------------------------------------- \n"
28    printf "  | %-20s |  %-10s   |  %-8s | \n" 'Section Name' 'Address' 'Size'
29    printf "   -------------------------------------------------- \n"
30
31    while IFS=$' \t\n\r' read -r line; do
32        local lineArray=($line)
33        local numElem=${#lineArray[@]}
34
35        # Only look at potentially valid lines
36        if [[ $numElem -ge 6 ]]; then
37            # Section headers
38            if [[ ${lineArray[0]} == "["* ]]; then
39                local sectionElement=NULL
40                local addrElement=00000000
41                local sizeElement=000000
42                for (( idx = 0 ; idx <= $numElem-4 ; idx = $idx+1 ));
43                do
44                    if [[ ${lineArray[$idx]} == *"]" ]]; then
45                        sectionElement=${lineArray[$idx+1]}
46                    fi
47                    # Look for regions with SHF_ALLOC = A
48                    if [[ ${#lineArray[idx]} -eq 8 ]] && [[ ${#lineArray[idx+1]} -eq 6 ]] && [[ ${#lineArray[idx+2]} -eq 6 ]] \
49                       && [[ ${lineArray[$idx+4]} == *"A"* ]] ; then
50                        addrElement=${lineArray[$idx]}
51                        sizeElement=${lineArray[$idx+2]}
52                    fi
53                done
54                # Only consider non-zero size sections
55                if [[ $addrElement != "00000000" ]]; then
56                    printf "  | %-20s |  0x%-10s |  %-8s | \n" $sectionElement $addrElement $((16#$sizeElement))
57                    # Use the section headers for SRAM tally
58                    if [[ "0x$addrElement" -ge "$STARTSRAM" ]] && [[ "0x$addrElement" -lt "$ENDSRAM" ]]; then
59                        internalSram=$((internalSram+$((16#$sizeElement))))
60                    fi
61                fi
62            # Program headers
63            elif [[ ${lineArray[1]} == "0x"* ]] && [[ ${lineArray[2]} == "0x"* ]] && [[ ${lineArray[3]} == "0x"* ]] && [[ ${lineArray[4]} == "0x"* ]]\
64                && [[ ${lineArray[3]} -ge "$STARTFLASH" ]] && [[ ${lineArray[3]} -lt "$ENDFLASH" ]]; then
65                # Use the program headers for Flash tally
66                internalFlash=$((internalFlash+${lineArray[4]}))
67            fi
68        fi
69    done < "$READELFFILE"
70
71    printf "   -------------------------------------------------- \n\n"
72    printf "  %-41s %-8s \n" 'Total Internal Flash (Available)' $AVAILABLEFLASH
73    printf "  %-41s %-8s \n\n" 'Total Internal Flash (Utilized)' $internalFlash
74    printf "  %-41s %-8s \n" 'Total Internal SRAM (Available)' $AVAILABLESRAM
75    printf "  %-41s %-8s \n" 'Total Internal SRAM (Utilized)' $internalSram
76}
77
78memcalc
79