5

Im writing a script for extracting all the functions (written by user) in a binary.

The following shell script extracts my function names as well as some library functions which start with __.

readelf -s ./a.out | gawk '
{ 
  if ($4 == "FUNC" && $3 != "0" && $7 == "13" && $8 != "main") { 
    print "b " $NF; //***Updated
  } 
}' &> function_names; 

Output of function_names file:

b __libc_csu_fini
b PrintDivider    
b PrintFooter    
b __libc_csu_init    
b PrintHeader

I would like to extract only my functions. So how to check whether function name starts with __ or else any other alternatives also highly appreciated.

Update::

@djf solution works fine. What if .c files which are compiled also may contain a function which starts with __? In that case, how to differentiate?

Jens
  • 69,818
  • 15
  • 125
  • 179
Jeyaram
  • 9,158
  • 7
  • 41
  • 63

3 Answers3

10

What about using readelf on your object file(s) instead of the linked executable? Then there's no spam from the library functions. Use the -c flag to compile to an object file and not link immediately.

PS: The proper tool to extract names from an executable or object file is nm, not readelf. Using nm -P file has everything you want.

$ nm -P tst.o | awk '$2 == "T" {print "b " $1}'
b foo
b main

EDIT: To ignore main and symbols starting with an underscore, use

$ nm -P a.out | awk '$2 == "T" && $1 !~ /^_/ && $1 != "main" {print "b " $1}'
Jens
  • 69,818
  • 15
  • 125
  • 179
5

You could add a regex check to make sure that the function name starts with a letter.

I presume that $8 contains the function name:

readelf -s ./a.out | gawk '
{
  if($4 == "FUNC" && $3 != "0" && $7 == "13" && $8 != "main" && $8~/^[[:alpha:]]/) {
    print $NF;
  }
}'
djf
  • 6,592
  • 6
  • 44
  • 62
  • If user defined function also starts with __, then how to differntiate ??? any idea?? pls share. – Jeyaram Jul 05 '13 at 11:15
  • 1
    @Jeyaram it's really bad practice to name your functions with leading underscores since these names are reserved for the compiler and core libraries... avoid doing that if you can - in C++ its forbidden by the language standard. I'm not sure about C, though. I can't tell you how to differentiate because you haven't told us what your function names look like... C-libraries usually add a prefix to all function names to avoid name clashes with other libraries. Maybe you could filter on such a prefix? – djf Jul 05 '13 at 11:23
1

Pipe it through grep ^[^_]. [30 char]

  • Thanks for your response. Can u please explain bit more ?? – Jeyaram Jul 05 '13 at 10:53
  • 1
    @Jeyaram Explain what? You pipe the output through this command and BOOM you get what you want. –  Jul 05 '13 at 10:53
  • @Jeyaram Now has your question changed? Or what? I don't understand. For me, it's still the same: grep for the names which don't begin by an underscore. –  Jul 05 '13 at 11:05
  • b is breakpoint command for gdb. so `b `. I want to use this file for gdb as input `--command` option. – Jeyaram Jul 05 '13 at 11:07
  • @Jeyaram Non sequitur. What is the problem now? –  Jul 05 '13 at 11:07
  • Any particular reason for the `.*$` part in the regex? – Jens Jul 05 '13 at 16:54
  • @Jens Yes, unless I include that, the answer is 28 chars long and SO doesn't let me submit it. –  Jul 05 '13 at 17:14
  • Ah, then I would have single quoted the regex to avoid the shell from globbing `^[^_]` in case there's a file named `^x` around... :-) – Jens Jul 06 '13 at 08:33