I finally solved this problem by getting some help from the gcc guys. See the thread here: http://gcc.gnu.org/ml/gcc-help/2010-09/msg00130.html.
It turns out that the .gcda files were being put in the .libs directory since that’s where the shared library (.so) files were. In order to get gcov to produce the output, I had to move the .gcda files up one level to where the source files were.
Also, here’s a similar thread where someone else was running into some of the same problems: can gcov deal with shared object?.