I've not used IDA much, so I can't say definitively what it might be capable of, but you can see the base load address of each dynamic library on which tivoapp depends in the backtrace resulting from a crash.
Typically something like this towards the end:
Code:
bt -t /tvbin/tivoapp <<END_OF_BT
read 0x2aaa8000 /lib/ld.so.1
read 0x2ab04000 /lib/libutil.so.1
read 0x2ab48000 /lib/libdl.so.2
read 0x2ab8c000 /lib/libpthread.so.0
read 0x2abe8000 /lib/libm.so.6
read 0x2acb0000 /lib/libc.so.6
0x00cede04 0x00b451cc 0x00b45898 0x00b39fe4 0x00b39270 0x013aa9dc 0x013aa794
0x013ac51c 0x013d3a50
END_OF_BT
In much older versions of software, tivoapp was statically linked, but from 7.x on, dynamically. Note as well that with ~7.2 on, the shared libraries appear to have been prelinked, as Jamie points out, so the jump address in tivoapp matches an address in the disassembly of the libs.
Rather that try to assemble all code into a single disassembly file, people have instead tried to determine the functions name/purpose and then add it to a .proc file so that the procedure description/name is annotated as a comment in the disassembly. It's much easier to parse the code that way, but that assumes one is using the tmesis postprocessor (I can't say if IDA offers something similar). Again, more details and discussion in the temsis thread here.
As for dynamically testing patches, I'm unsure if it's possible to do. There are many confounding factors (an array of virtually indistinguishable tivoapps [the SwedishChef] and the possibility that the code caches various results [especially so with network related operations] to name two). There's definitely a balance between time spent on static disassembly analysis versus empirical testing when devising a new patch.