1

A linux stat64 call is supposed to end up calling xstat64 with a static version of stat64 generated that passes a version along with the call.

We are seeing a condition where a C linked (gcc) version of code that calls stat64, when linked against an older version of a (C++ linked) shared library (libdb2.so.1, that uses stat64, but isn't supposed to provide it), is not ending up with a the "proper" static version of this stat64 call. The C++ linked app has what we expect:

00000000004007c8 <__xstat64@plt>:
  4007c8:  jmpq   *1051250(%rip)        # 501240 <_GLOBAL_OFFSET_TABLE_+0x20>
  4007ce:  pushq  $0x1
  4007d3:  jmpq   4007a8 <_init+0x18>

0000000000400ac0 <stat64>:
  400ac0:  push   %rbp
  400ac1:  mov    %rsp,%rbp
  400ac4:  sub    $0x10,%rsp
  400ac8:  mov    %rdi,0xfffffffffffffff8(%rbp)
  400acc:  mov    %rsi,0xfffffffffffffff0(%rbp)
  400ad0:  mov    0xfffffffffffffff0(%rbp),%rdx
  400ad4:  mov    0xfffffffffffffff8(%rbp),%rsi
  400ad8:  mov    $0x1,%edi
  400add:  callq  4007c8 <__xstat64@plt>
  400ae2:  leaveq
  400ae3:  retq

whereas the gcc linked code (that also links to our libdb2 shared lib) ends up with a global reference to stat64 instead of the "static" version that it is suppose to have:

0000000000400618 <stat64@plt>:
  400618:   jmpq   *1050146(%rip)        # 500c40 <_GLOBAL_OFFSET_TABLE_+0x20>
  40061e:   pushq  $0x1
  400623:   jmpq   4005f8 <_init+0x18>

The same code, also when linked with gcc, when not linked to our libdb2 library, ends up with the expected "static" stat64 function:

0000000000400550 <__xstat64@plt>:
  400550:   jmpq   *1050170(%rip)        # 500b90 <_GLOBAL_OFFSET_TABLE_+0x20>
  400556:   pushq  $0x1
  40055b:   jmpq   400530 <_init+0x18>

00000000004007b0 <stat64>:
  4007b0:   mov    %rsi,%rdx
  4007b3:   mov    %rdi,%rsi
  4007b6:   mov    $0x1,%edi
  4007bb:   jmpq   400550 <__xstat64@plt>

EDIT: more info obtained from a linker map (-Wl,--print-map)

When the gcc linked exe doesn't link to our (libdb2) shared lib, we see that it gets it's stat64 from libc_nonshared.a:

/usr/lib64/libc_nonshared.a(stat64.oS)
                              /home/hotellnx94/peeterj/tmp/cc2f7ETx.o (stat64)
...

.plt            0x0000000000400530       0x70
 *(.plt)
 .plt           0x0000000000400530       0x70 /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crt1.o
                0x0000000000400540                __libc_start_main@@GLIBC_2.2.5
                0x0000000000400550                __xstat64@@GLIBC_2.2.5
                0x0000000000400560                printf@@GLIBC_2.2.5
                0x0000000000400570                memset@@GLIBC_2.2.5
                0x0000000000400580                strerror@@GLIBC_2.2.5
                0x0000000000400590                __errno_location@@GLIBC_2.2.5

 .text          0x00000000004007b0       0x10 /usr/lib64/libc_nonshared.a(stat64.oS)
                0x00000000004007b0                stat64

whereas, once we link to our shared lib (libdb2), the symbols are picked up from crt1.o instead of lib_nonshared.a:

.plt            0x00000000004005f8       0x70
 *(.plt)
 .plt           0x00000000004005f8       0x70 /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crt1.o
                0x0000000000400608                __libc_start_main@@GLIBC_2.2.5
                0x0000000000400618                stat64
                0x0000000000400628                printf@@GLIBC_2.2.5
                0x0000000000400638                memset@@GLIBC_2.2.5
                0x0000000000400648                strerror@@GLIBC_2.2.5
                0x0000000000400658                __errno_location@@GLIBC_2.2.5

What could we be doing (or would have been doing since we don't see this in new versions of our library), that would cause lib_nonshared.a to no longer be shared once the consumer links to our library?

Peeter Joot
  • 7,848
  • 7
  • 48
  • 82

1 Answers1

1

It turned out that this was due to an intel compiler bug that was fixed. When we started using the compiler version that had the fix we were then exposed to a binary compatibility issue since the new version of the intel compiler (producing the shared lib in question), properly didn't export this stat64 symbol.

Peeter Joot
  • 7,848
  • 7
  • 48
  • 82