#!/bin/sh if [ $# -lt 1 ]; then echo "Usage: $0 " exit 1 fi image=$1 if [ ! -r $image ]; then echo "Image $image not readable" exit 1 fi objdump -hD $image | awk ' BEGIN { init_start="ffffffff" init_end="ffffffff" } / .text.init/ { # # Get the start address of init section of section header information # if (init_start == "ffffffff") { init_start=$4 printf("Start of init section: %s\n", init_start) >> "/dev/tty" } } / .data.page_aligned/ { # # Get the end address of init section of section header information # if (init_end == "ffffffff") { init_end=$4 printf("End of init section: %s\n", init_end) >> "/dev/tty" } } />:$/ { # # Start of a function # current_func = $2 gsub("[<>:]", "", current_func) in_address = $1 if (in_address >= init_start && in_address < init_end) function_prefix = "@"; else function_prefix = "&"; export_definition = index(current_func, "__kstrtab_"); init_call = index(current_func, "__initcall_"); setup_call = index(current_func, "__setup_"); if (export_definition) { current_func = substr(current_func, export_definition + 10) current_func = function_prefix current_func user[current_func] = user[current_func] " EXPORT" } else if (init_call) { current_func = substr(current_func, init_call + 11) current_func = function_prefix current_func user[current_func] = user[current_func] " INITCALL" } else if (setup_call) { current_func = substr(current_func, setup_call + 8) current_func = function_prefix current_func user[current_func] = user[current_func] " SETUPCALL" } else { current_func = function_prefix current_func user[current_func] = ": " user[current_func] } printf("%s: %s\n", in_address, current_func) >> "/dev/tty" } /call / { # # A call instruction of a function # stmt = substr($0, index($0, "call ")) num = split(stmt, col); if (num == 3) { name = col[3] address = col[2] gsub("[<>]", "", name) if (address >= init_start && address < init_end) name = "@" name else name = "&" name user[name] = user[name] " " current_func } } END { for (fnc in user) printf("%s%s\n", fnc, user[fnc]) } ' > user_map echo "" echo "" echo "List of all functions with their users are in file user_map." echo " Function prefix '@' means: function is in .text.init section" echo " Function prefix '&' means: function is in ordinary .text section" echo "" echo "TODO List:" echo "1. Deal with collisions in function name space" echo "2. Deal with data" echo "3. Deal with function pointers in structs or function parameters" echo "" echo "" echo "List of all potential init functions:" echo "-------------------------------------" grep "^&" user_map | cut -c2- | grep -v "&" | grep -v ": $" | grep -v EXPORT