Bug 1061501

Summary: libdwarf is not linked to libelf
Product: Red Hat Enterprise Linux 7 Reporter: Josh Stone <jistone>
Component: libdwarfAssignee: Frank Ch. Eigler <fche>
Status: CLOSED ERRATA QA Contact: Michael Petlan <mpetlan>
Severity: unspecified Docs Contact:
Priority: medium    
Version: 7.0CC: mbenitez, mcermak, mpetlan, orion, tom
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: libdwarf-20130207-4.el7 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: 1061432 Environment:
Last Closed: 2015-03-05 10:55:17 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1061432    
Bug Blocks:    

Description Josh Stone 2014-02-05 00:27:54 UTC
+++ This bug was initially created as a clone of Bug #1061432 +++

Description of problem:
libdwarf is built with elfutils-libelf-devel, but it doesn't actually link libelf.so.  This means rpm doesn't know about this library dependency, and clients also have to link -lelf even when they don't use libelf directly.

Version-Release number of selected component (if applicable):
libdwarf-20140131-1.fc20.x86_64

How reproducible:
100%

Steps to Reproduce:
1. readelf -d /usr/lib64/libdwarf.so.0 | grep NEEDED
2. rpm -qR libdwarf | grep libelf
3. echo 'int main(){return 0;}' | gcc -x c - -o /dev/null -ldwarf

Actual results:
1. only NEEDED is libc.so
2. (nothing)
3. libdwarf.so: undefined reference to `elf32_getehdr' ... and many more.

Expected results:
1. There should be a NEEDED line for libelf.so.1
2. It should get an auto-require like "libelf.so.1()(64bit)" (from NEEDED).
3. With the library properly linked, clients won't need their own -lelf

Additional info:
The missing rpm dependency is unlikely to ever be an issue in practice, because rpm itself requires libelf, so it will always be present anyway.  However, I do find it bad practice that clients must use -lelf on libdwarf's behalf.  (Compare the same step-3 test with -ldw, for instance.)

--- Additional comment from Tom Hughes on 2014-02-04 13:30:03 PST ---

I think this is, at least from upstream's point of view, deliberate as it is possible to use libdwarf without libelf.

Basically if you use dwarf_object_init instead of dwarf_init of dwarf_elf_init that libelf won't be used and access to the object will be via the callbacks provided in the Dwarf_Obj_Access_Interface structure.

Of couse that doesn't mean we might not want to pull in libelf by default in Fedora.

--- Additional comment from Josh Stone on 2014-02-04 14:16:14 PST ---

It might be possible to avoid libelf if you link libdwarf.a, but when you use libdwarf.so then all symbols have to be resolved to compile and run, even the parts you won't be using.  That's why my example 3, which doesn't actually *use* libdwarf at all, must still add -lelf to link correctly.

In other words, static libdwarf work fine:
> $ echo 'int main(){return 0;}' | gcc -x c - -o /dev/null -static -ldwarf
> $ echo $?
> 0

But shared libdwarf fails:
> $ echo 'int main(){return 0;}' | gcc -x c - -o /dev/null -ldwarf
> /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/libdwarf.so: undefined reference to `elf32_getehdr'
> /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/libdwarf.so: undefined reference to `elf_getscn'
> /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/libdwarf.so: undefined reference to `elf_begin'
> /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/libdwarf.so: undefined reference to `elf64_getshdr'
> /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/libdwarf.so: undefined reference to `elf_end'
> /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/libdwarf.so: undefined reference to `elf64_getehdr'
> /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/libdwarf.so: undefined reference to `elf_strptr'
> /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/libdwarf.so: undefined reference to `elf_getident'
> /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/libdwarf.so: undefined reference to `elf32_getshdr'
> /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/libdwarf.so: undefined reference to `elf_version'
> /usr/lib/gcc/x86_64-redhat-linux/4.8.2/../../../../lib64/libdwarf.so: undefined reference to `elf_getdata'
> collect2: error: ld returned 1 exit status
> $ echo $?
> 1

It's ok again with libelf forced in:
> $ echo 'int main(){return 0;}' | gcc -x c - -o /dev/null -ldwarf -lelf
> $ echo $?
> 0

And here's the comparison I made to -ldw, which links libelf itself:
> $ echo 'int main(){return 0;}' | gcc -x c - -o /dev/null -ldw
> $ echo $?
> 0

--- Additional comment from Tom Hughes on 2014-02-04 14:49:40 PST ---

Well strictly speaking you can make it link with --allow-shlib-undefined but yes, it is enough of an edge case that it would probably make more sense to pull libelf in by default.

--- Additional comment from Fedora Update System on 2014-02-04 15:58:09 PST ---

libdwarf-20140131-2.fc20 has been submitted as an update for Fedora 20.
https://admin.fedoraproject.org/updates/FEDORA-2014-1926/libdwarf-20140131-2.fc20

--- Additional comment from Josh Stone on 2014-02-04 16:17:06 PST ---

Thanks for the quick fix - it looks good to me.

(In reply to Josh Stone from comment #0)
> The missing rpm dependency is unlikely to ever be an issue in practice,
> because rpm itself requires libelf, so it will always be present anyway.

FWIW, I realized a case where this isn't true, which is multilib.  If you install libdwarf.i686 on x86_64, you may not already have elfutils-libelf.i686, so it ought to be pulled in as a dependency.  I confirmed that this didn't happen before, but it works with the new build.

Comment 1 Josh Stone 2014-02-05 00:29:26 UTC
Tom's fix for Fedora basically just adds -lelf to the existing soname patch.

Comment 5 Michael Petlan 2014-11-20 19:54:52 UTC
Tested with libdwarf-20130207-4.el7.x86_64.

VERIFIED.

Comment 7 errata-xmlrpc 2015-03-05 10:55:17 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHBA-2015-0483.html