[BACK]Return to elf.html CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / htdocs / docs

File: [cvs.NetBSD.org] / htdocs / docs / elf.html (download) (as text)

Revision 1.73, Mon May 17 12:47:46 2021 UTC (5 months ago) by martin
Branch: MAIN
CVS Tags: HEAD
Changes since 1.72: +4 -4 lines

Regen for 9.2

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="generator" content="Website XSL Stylesheet V2.6.0">
<link rel="home" href="../." title="Welcome to The NetBSD Project: Of course it runs NetBSD.">
<link rel="up" href="../docs/." title="NetBSD Documentation">
<link rel="previous" href="../docs/compat.html" title="NetBSD Binary Emulation">
<link rel="next" href="../docs/encrypted-iscsi.html" title="Encrypted iSCSI Devices on NetBSD">
<link rel="first" href="../docs/Hardware/." title="Hardware Documentation">
<link rel="last" href="../docs/x/." title="NetBSD Documentation: The X Window System">
<link rel="stylesheet" href="../global.css" type="text/css">
<link rel="stylesheet" href="../donations/thermo/fundraiser.css" type="text/css">

  
  

  <title>NetBSD ELF FAQ</title>
</head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<body class="website"><div class="webpage">
<a name="docs-elf"></a><div id="top"><a href="#mainContent" id="skiplink" tabindex="1">Skip to main content.</a></div>
<input id="hamburger" type="checkbox"><label class="menuicon" for="hamburger"><span></span><span></span><span></span></label><div id="navBar" role="navigation">
<div id="centralHeader"><div id="logo">
<a href="../"><img id="projectLogo" alt="" height="120" src="../images/NetBSD-smaller-tb.png"></a><a href="/"><div id="fundraiser">
<br><div id="fundraiser-amount"><div id="fundraiser-raised"></div></div>
</div></a>
</div></div>
<span class="doNotDisplay">
	  Navigation:
	</span><ul>
<li>
<a href="../">
	  Home</a><ul>
<li><a href="../changes/">
	    Recent changes</a></li>
<li><a href="//blog.NetBSD.org/">
	    NetBSD blog</a></li>
<li><a href="../gallery/presentations/">
	    Presentations</a></li>
</ul>
</li>
<li>
<a href="../about/">
	  About</a><ul>
<li><a href="../people/developers.html">
	    Developers</a></li>
<li><a href="../gallery/">
	    Gallery</a></li>
<li><a href="//wiki.NetBSD.org/ports/">
	    Ports</a></li>
<li><a href="//www.pkgsrc.org/">
	    Packages</a></li>
</ul>
</li>
<li>
<a href="../docs/">
	  Documentation</a><ul>
<li><a href="../docs/misc/index.html">
	    FAQ &amp; HOWTOs</a></li>
<li><a href="../docs/guide/en/">
	    The Guide</a></li>
<li><a href="//man.NetBSD.org/">
	    Manual pages</a></li>
<li><a href="//wiki.NetBSD.org/">
	    Wiki</a></li>
</ul>
</li>
<li>
<a href="../support/">
	  Support</a><ul>
<li><a href="/community/">
	    Community</a></li>
<li><a href="/mailinglists/">
	    Mailing lists</a></li>
<li><a href="../support/send-pr.html">
	    Bug reports</a></li>
<li><a href="../support/security/">
	    Security</a></li>
</ul>
</li>
<li>
<a href="../developers/">
	  Developers</a><ul>
<li><a href="http://cvsweb.NetBSD.org/">
	    CVSWeb</a></li>
<li><a href="//anonhg.NetBSD.org/">
	    Mercurial</a></li>
<li><a href="//nxr.NetBSD.org/">
	    Cross-reference</a></li>
<li><a href="//releng.NetBSD.org/">
	    Release engineering</a></li>
<li><a href="//wiki.NetBSD.org/projects/">
	    Projects list</a></li>
</ul>
</li>
</ul>
</div>
<div id="content"><div id="mainContent" class="fullWidth"><div class="rowOfBoxes">
<h1>NetBSD ELF FAQ</h1>
<h3 class="title"><a name="elf-issues">ELF Issues</a></h3>
<ul>
<li><a href="#elf-whatis">What is ELF?</a></li>
<li><a href="#elf-dynamic-callbacks">A dynamically loaded module at run-time couldn't find symbols 
	from my program image.</a></li>
<li><a href="#elf-ldconfig">No need for ldconfig or for 
      	ld.so.conf!</a></li>
<li><a href="#elf-rpath">My program can't find its shared library</a></li>
<li><a href="#elf-examples">Elf Shared Library Examples</a></li>
<li><a href="#elf-ldconfig-revisited">But I Want ldconfig! I Want ld.so.conf!  I want it! I want it! I want it!</a></li>
<li><a href="#elf-how-to-tell">How do I tell if my system is ELF?</a></li>
</ul>
<hr>
<h3 class="title">ELF Issues</h3>
      <h4 class="title">
<a name="elf-whatis"></a>What is ELF?</h4>

      <p>ELF is a binary format designed to support dynamic objects 
	and shared libraries. On older COFF and ECOFF systems, dynamic 
	support and shared libraries were not naturally supported by the 
	underlying format, leading to dynamic implementations that were 
	at times complex, quirky, and slow.</p>
    
      <h4 class="title">
<a name="elf-dynamic-callbacks"></a>A dynamically loaded module at run-time couldn't find symbols 
	from my program image.</h4>

      <p>You probably left off the 
	<span class="bold"><strong>--export-dynamic</strong></span> option when
	linking the application. This is required only if arbitrary symbols 
	in the program might be needed by the dynamically loaded module, 
	for example, if a program intends to make run-time decisions to 
	dynamically load modules it was never linked with. Note, when
	running <a href="//man.NetBSD.org/NetBSD-9.2/i386/cc.1">cc(1)</a> instead of <a href="//man.NetBSD.org/NetBSD-9.2/i386/ld.1">ld(1)</a> this will be specified 
	as <span class="bold"><strong>-Wl,--export-dynamic</strong></span>.</p>
    
      <h4 class="title">
<a name="elf-ldconfig"></a>No need for ldconfig or for 
      	<code class="filename">ld.so.conf</code>!</h4>

      <p>Ideally, there is no need for ldconfig or for  
      	<code class="filename">/etc/ld.so.conf</code>,
	since ELF provides good and predictable (read portable) mechanism
	to locate shared libraries. Unfortunately there are still a few
	corner cases (like wanting to run setuid binaries that you don't
	have the source for, that want shared libraries to be installed
	somewhere you don't like). For those corner cases, you'll find that
	creating an <code class="filename">/etc/ld.so.conf</code> file, will 
	still work. Read on though
	about other ways of doing this and why it is not a good idea. The
	next section discusses the ELF mechanisms for locating shared
	libraries.</p>
    
      <h4 class="title">
<a name="elf-rpath"></a>My program can't find its shared library</h4>

      <p>An ELF program needs to know the <span class="emphasis"><em>directory</em></span> 
	and the <span class="emphasis"><em>filename</em></span> required to <a href="//man.NetBSD.org/NetBSD-9.2/i386/mmap.2">mmap(2)</a> 
	its shared libraries. Encoded within the file name is version 
	information. There are one set of mechanisms for the directories 
	and a different mechanism for the file names.</p>
	
      <div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="elf-rpath-dir"></a>Directories</h5></div></div></div>
	

	<p>Although rarely used, the optional
	  <code class="code">LD_LIBRARY_PATH</code> environment variable specifies
	  a colon-separated search path. This can be used in wrapper 
	  scripts as needed for misconfigured applications. It is 
	  <span class="emphasis"><em>ignored</em></span> for setuid binaries.</p>
	
	<p>There is a built-in search path in the run-time loader:
	  <code class="filename">ld.elf_so</code>. On many systems this path 
	  consists only of <code class="filename">/usr/lib</code>; although on 
	  NetBSD versions prior to 1.4 it also searched
	  <code class="filename">/usr/local/lib</code>.</p>

	<p>The primary directory locating mechanism is the ``rpath'' 
	  search list contained within the executable image. This search 
	  list is set with the <span class="bold"><strong>-R</strong></span>
	  directive to <a href="//man.NetBSD.org/NetBSD-9.2/i386/ld.1">ld(1)</a>. The POSIX syntax for passing
	  <a href="//man.NetBSD.org/NetBSD-9.2/i386/ld.1">ld(1)</a> options through the compiler front end is:</p>

	<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="bold"><strong>-Wl,</strong></span>
	  <span class="emphasis"><em>option,option,...</em></span></p>
	  
	<p>For example: <code class="code">-Wl,-R/usr/something/lib</code>.
	  Multiple <span class="bold"><strong>-R</strong></span> directives can be 
	  given to a single application to create a shared library
	  search path.</p>

	<p>This directive is also known as 
	  <span class="bold"><strong>-rpath</strong></span>. Using 
	  <span class="bold"><strong>-R</strong></span> has the advantage of 
	  working in older versions of NetBSD as well.</p>
      </div>

      <div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="elf-rpath-versions"></a>File Names and Versions</h5></div></div></div>
        

	<p>When shared libraries are created, the <span class="bold"><strong>-soname</strong></span> directive is used to record 
	  the major version number of the library in the internal 
	  <code class="code">DT_SONAME</code> field. The actual library is installed 
	  as, for example,</p>

	  <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="filename">libgizmo.so.4.2</code> 
	      &nbsp;&nbsp;<span class="emphasis"><em>(the actual file)</em></span>
</li>
<li class="listitem">
<code class="filename">libgizmo.so.4</code>
	      &nbsp;&nbsp;<span class="emphasis"><em>(symbolic link)</em></span>
</li>
<li class="listitem">
<code class="filename">libgizmo.so</code>
	      &nbsp;&nbsp;<span class="emphasis"><em>(symbolic link)</em></span>
</li>
</ul></div>

	<p>The idea is that Makefiles will want to link against only
	  the plain .so file. (Who would want to go around changing all 
	  the Makefiles just because a new library version was 
	  installed?) Once linked, however, the program 
	  <span class="emphasis"><em>does</em></span> want to be aware of the major 
	  version but does <span class="emphasis"><em>not</em></span> want to deal 
	  with the minor version.</p>

	<p>Consequently, the library itself knows that it is
	  <code class="filename">libgizmo.so.4</code> because a <span class="bold"><strong>-soname <code class="filename">libgizmo.so.4</code></strong></span>
	  directive was used when it was created. The program knows 
	  it got major version 4 because the linker copied the
	  <code class="filename">libgizmo.so.4</code> <code class="code">DT_SONAME</code> string 
	  out of the library and saved it in the executable.</p>

	<p>You don't say <span class="bold"><strong>-soname <code class="filename">libgizmo.so</code></strong></span>, 
	  because then the program would use the latest major number 
	  and would break if that ever changed. (The major number only 
	  changes if the new library is incompatible.)
	  You don't say <span class="bold"><strong>-soname <code class="filename">libgizmo.so.4.2</code></strong></span>,
	  because then the installation of a compatible change that 
	  bumps the minor number would unnecessarily break the linked 
	  images.</p>
      </div>
    
      <h4 class="title">
<a name="elf-examples"></a>Elf Shared Library Examples</h4>

      <p>To compile <code class="filename">f.c</code> and make an installable 
      	shared library out of it:</p>

	<pre class="programlisting">cc -O  -Werror  -c -fpic -DPIC f.c -o f.so
ar cq libf_pic.a `NM=nm lorder f.so | tsort -q`
ld -x -shared -R/my/directory/lib -soname libf.so.4 -o \
&nbsp;&nbsp;&nbsp;libf.so.4.9  /usr/lib/crtbeginS.o  --whole-archive \
&nbsp;&nbsp;&nbsp;libf_pic.a /usr/lib/crtendS.o</pre>

      <p>There is another way:</p>
      
      <pre class="programlisting">% cat Makefile
LIB=f
SRCS=f.c
.include &lt;bsd.lib.mk&gt;
% cat shlib_version
major=4
minor=9
% make

You can disable some of the <code class="code">Makefile</code> targets with NOPROFILE=1 and NOSTATICLIB=1.</pre>

      <p>And there is <span class="emphasis"><em>another</em></span> way:</p>

      <div class="blockquote"><blockquote class="blockquote">
<code class="code">libtool</code> -
	The <code class="code">libtool</code> package is a large shell script used to
	manage shared and static libraries in a platform-independent fashion.
	There is a NetBSD <a href="https://cdn.NetBSD.org/pub/pkgsrc/current/pkgsrc/devel/libtool/index.html" target="_top"><code class="filename">devel/libtool</code></a> package
	and even a <a class="ulink" href="http://www.gnu.org/software/libtool/libtool.html" target="_top">
	<code class="code">libtool</code> home page</a>.
      </blockquote></div>
    
      <h4 class="title">
<a name="elf-ldconfig-revisited"></a>But I Want ldconfig! &nbsp;&nbsp;&nbsp;I Want ld.so.conf!  I want it! I want it! I want it!</h4>

      <p>At first glance, it might seem reasonable, why shouldn't 
	people be able to move things around to anywhere they want and
	correct the consequent lossage in a 
	<code class="filename">/etc</code> file?</p>
      
      <p>In fact, some developers of ELF systems have apparently
	added such a file, but with mixed results. The ELF mechanism 
	was designed to correct some of the previous problems, and 
	introducing the old mechanism would bring many of those old 
	problems back.</p>

      <p>Currently we are even supporting the
	<code class="filename">/etc/ld.so.conf</code> functionality
	in our ELF linker, but it is not at all clear that a hybrid 
	mechanism is the right solution. For that reason we do not 
	advertise its existence, advocate its use, or even provide a 
	default installation template. It is there for those who think 
	that they really need it, and cannot live without it.</p>

      <p>Here are some of the problems.
	
	</p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">It's a shotgun approach that incorrectly assumes all
	    images on the system will want to use the same search path.
	    One advantage of the <span class="bold"><strong>-R</strong></span>
	    mechanism is that different applications can use different
	    library search paths.
	    We could add exceptions to this, but it's more configuration
	    steps...see below...</li>
<li class="listitem">Another file in <code class="filename">/etc</code> is yet 
	    another configuration knob to turn. This works against making 
	    the system easy to install and use.</li>
<li class="listitem">The <code class="filename">/etc</code> file gets out of sync 
	    with the installed system when configurations are changed or 
	    packages are added. The resulting failure mode can be confusing 
	    to some users.</li>
<li class="listitem">The system should `just work'. We don't want to have 
	    to indoctrinate users into editing the config file for
	    packages, X11, <code class="filename">/usr/local</code>.</li>
<li class="listitem">Would you think it is reasonable to provide a local
	    configuration search path for random data configuration
	    files? Would a single path really apply for all applications?
	    What if two applications had the same configuration file?
	    What if two packages each want a
	    "<code class="filename">libutil.so.1</code>"?</li>
</ol></div>
<p>
      </p>

      <p>ELF tools are standardized packages maintained by third
	parties; these tools are used consistently on different operating 
	systems and platforms. In the long run, the standardization 
	provided by ELF will increase the quality of both systems and 
	applications.</p>
    
      <h4 class="title">
<a name="elf-how-to-tell"></a>How do I tell if my system is ELF?</h4>
	
      <p>If you are running an ELF system your compiler will define 
	the constant <span class="emphasis"><em>__ELF__</em></span>. You can use this in 
	your C programs of course but you can also use the following 
	shell script to determine it as well.</p>
	
      <pre class="programlisting">if echo __ELF__ | ${CC:-cc} -E - | grep -q __ELF__
then echo "Not ELF"
else echo "It is an ELF system"
fi</pre>
    <hr>Back to em><a href="./">NetBSD Documentation Top Level</a></em>
</div></div></div>
<div class="navfoot"></div>
<div id="footer"><div id="footerContent"><center>
<span class="footfeed"><a href="//www.NetBSD.org/cgi-bin/feedback.cgi">
	  Contact</a> |
      </span><span class="footcopy"><a href="../about/disclaimer.html">
      Disclaimer</a> |

      <span class="copyright">Copyright 1994-2021 The NetBSD Foundation, Inc. </span>ALL RIGHTS RESERVED.<br>NetBSD<sup>/sup> is a registered trademark of The NetBSD
	Foundation, Inc.</span>
</center></div></div>
</div></body>
</html>