title: Rewrite shared library undef symbol version of compiled object
body: <p>I am trying to compile and link a program (let's call it myprog) which is linked against a shared library (in this instance <strong>libcryto &amp; libssl</strong>, but the actual library is not relevant). I am building it on <strong>Centos 5.5</strong> but want the same binary to run on other <strong>RHEL</strong>-like distributions (e.g. CloudLinux). Both have versions of the same library with the same <code>SO_NAME</code> (i.e. <code>DT_NEEDED</code> versions correspond).</p>
  
  <p>My issue is this. When I compile on Centos I see:</p>
  
  <pre><code>centos$ objdump -T myprog | fgrep SSL_new
  0000000000000000      DF *UND*  0000000000000000  libssl.so.10 SSL_new
  </code></pre>
  
  <p>which works fine because:</p>
  
  <pre><code>centos$ objdump -T /usr/lib64/libssl.so.10 | fgrep SSL_new
  00000000000447d0 g    DF .text  0000000000000390  libssl.so.10 SSL_new
  </code></pre>
  
  <p>However, on CloudLinux:</p>
  
  <pre><code>cloudlinux$ objdump -T /usr/lib64/libssl.so.10 | fgrep SSL_new
  00000033a623a120 g    DF .text  0000000000000390  Base        SSL_new
  </code></pre>
  
  <p>Note the version of the SSL symbol has changed from <code>libssl.so.10</code> to <code>Base</code>.</p>
  
  <p>This means when I run the binary I get:</p>
  
  <pre><code>cloudlinux$ ./myprog
  ./myprog: /usr/lib64/libcrypto.so.10: no version information available (required by ./myprog)
  ./myprog: /usr/lib64/libssl.so.10: no version information available (required by ./myprog)
  </code></pre>
  
  <p>I understand this is 'just a warning', but I want to get rid of it.</p>
  
  <p>What I want is for my binary to run on both cloudlinux and centos without warnings. The ABI of the openssl libraries are, as far as I can tell, identical at least in the bits I use. Now I can't change the shared libraries as <code>myprog</code> is meant to run on any cloudlinux or centos libraries. I would accept a solution which at install time fixed up the symbols (somehow), e.g. with <code>objcopy</code>.</p>
  
  <p>One approach would be something like introduce a weak symbol for <code>SSL_new@libssl.so.10</code> which  is an alias for <code>SSL_new@Base</code>. Obviously that would be for every single symbol in the ssl library (so wrappers are not appropriate). But I can't get <code>-Wl,--defsym=x=y</code> to take values of <code>x</code> and <code>y</code> with <code>@</code> symbols in.</p>
  
  <p>Another approach that might work is simply to remove the symbol versioning information from the binary (i.e. remove the <code>libssl.so.10</code> version from each of the ssl symbols, and rely on the versioning within the <code>DT_NEEDED</code> name). This would seem to be a simple request, but I can't see how to do it either. Is there some <code>objcopy</code> incantation?</p>
  
  <p>Worse case, building on Centos a (separate) version that would work on CloudLinux would be fine. I tried by doing this:</p>
  
  <pre><code>#define OSLB(SYMNAME) __asm__(".symver " #SYMNAME "," #SYMNAME "@Base");
  OSLB (SSL_new);
  </code></pre>
  
  <p>However, that fails on link complaining that <code>SSL_new@Base</code> is an undefined symbol (which it is, on Centos, as the Centos <code>.so</code> does not have that symbol).</p>
  
  <p>Is there some way around this?</p>