Home | History | Annotate | Download | only in devcycle
      1 {{+bindTo:partials.standard_nacl_article}}
      2 
      3 <section id="dynamic-linking-and-loading-with-glibc">
      4 <h1 id="dynamic-linking-and-loading-with-glibc">Dynamic Linking and Loading with glibc</h1>
      5 <div class="contents local" id="contents" style="display: none">
      6 <ul class="small-gap">
      7 <li><p class="first"><a class="reference internal" href="#introduction" id="id1">Introduction</a></p>
      8 <ul class="small-gap">
      9 <li><a class="reference internal" href="#c-standard-libraries-glibc-and-newlib" id="id2">C standard libraries: glibc and newlib</a></li>
     10 <li><a class="reference internal" href="#sdk-toolchains" id="id3">SDK toolchains</a></li>
     11 <li><a class="reference internal" href="#specifying-and-delivering-shared-libraries" id="id4">Specifying and delivering shared libraries</a></li>
     12 </ul>
     13 </li>
     14 <li><a class="reference internal" href="#building-a-dynamically-linked-application" id="id5">Building a dynamically linked application</a></li>
     15 <li><a class="reference internal" href="#generating-a-native-client-manifest-file-for-a-dynamically-linked-application" id="id6">Generating a Native Client manifest file for a dynamically linked application</a></li>
     16 <li><a class="reference internal" href="#deploying-a-dynamically-linked-application" id="id7">Deploying a dynamically linked application</a></li>
     17 <li><a class="reference internal" href="#opening-a-shared-library-at-runtime" id="id8">Opening a shared library at runtime</a></li>
     18 <li><a class="reference internal" href="#troubleshooting" id="id9">Troubleshooting</a></li>
     19 </ul>
     20 
     21 </div><section id="introduction">
     22 <h2 id="introduction">Introduction</h2>
     23 <aside class="caution">
     24 Portable Native Client currently only supports static linking, and the
     25 only C library available for it is newlib. This page is only valid for
     26 Native Client, though PNaCl will eventually support some form of
     27 dynamic linking.
     28 </aside>
     29 <p>This document describes how to create and deploy dynamically linked and loaded
     30 applications with the glibc library in the Native Client SDK. Before reading
     31 this document, we recommend reading <a class="reference internal" href="/native-client/devguide/devcycle/building.html"><em>Building Native Client Modules</em></a></p>
     32 <section id="c-standard-libraries-glibc-and-newlib">
     33 <span id="c-libraries"></span><h3 id="c-standard-libraries-glibc-and-newlib"><span id="c-libraries"></span>C standard libraries: glibc and newlib</h3>
     34 <p>The Native Client SDK comes with two C standard libraries &#8212; glibc and
     35 newlib. These libraries are described in the table below.</p>
     36 <table border="1" class="docutils">
     37 <colgroup>
     38 </colgroup>
     39 <thead valign="bottom">
     40 <tr class="row-odd"><th class="head">Library</th>
     41 <th class="head">Linking</th>
     42 <th class="head">License</th>
     43 <th class="head">Description</th>
     44 </tr>
     45 </thead>
     46 <tbody valign="top">
     47 <tr class="row-even"><td>glibc</td>
     48 <td>dynamic
     49 or static</td>
     50 <td>GNU Lesser
     51 General
     52 Public
     53 License
     54 (LGPL)</td>
     55 <td>glibc is the GNU implementation of the
     56 <a class="reference external" href="http://en.wikipedia.org/wiki/POSIX">POSIX</a> standard runtime library for the C
     57 programming language. Designed for
     58 portability and performance, glibc is one
     59 of the most popular implementations of the
     60 C library. It is comprised of a set of
     61 interdependent libraries including libc,
     62 libpthreads, libdl, and others. For
     63 documentation, FAQs, and additional
     64 information about glibc, see <a class="reference external" href="http://www.gnu.org/software/libc/index.html">GLIBC</a></td>
     65 </tr>
     66 <tr class="row-odd"><td>newlib</td>
     67 <td>static</td>
     68 <td>Berkeley
     69 Software
     70 Distribution
     71 (BSD) type
     72 free
     73 software
     74 licenses</td>
     75 <td>newlib is a C library intended for use in
     76 embedded systems. Like glibc, newlib is a
     77 conglomeration of several library parts.
     78 It is available for use under BSD-type free
     79 software licenses, which generally makes it
     80 more suitable to link statically in
     81 commercial, closed-source applications. For
     82 documentation, FAQs, and additional
     83 information about newlib, see the <a class="reference external" href="http://sourceware.org/newlib/">newlib</a>
     84 documentation.</td>
     85 </tr>
     86 </tbody>
     87 </table>
     88 <p>For proprietary (closed-source) applications, your options are to either
     89 statically link to newlib, or dynamically link to glibc. We recommend
     90 dynamically linking to glibc, for a couple of reasons:</p>
     91 <ul class="small-gap">
     92 <li>The glibc library is widely distributed (it&#8217;s included in Linux
     93 distributions), and as such it&#8217;s mature, hardened, and feature-rich. Your
     94 code is more likely to compile out-of-the-box with glibc.</li>
     95 <li>Dynamic loading can provide a big performance benefit for your application if
     96 you can structure the application to defer loading of code that&#8217;s not needed
     97 for initial interaction with the user. It takes some work to put such code in
     98 shared libraries and to load the libraries at runtime, but the payoff is
     99 usually worth it. In future releases, Chrome may also support caching of
    100 common dynamically linked libraries such as libc.so between applications.
    101 This could significantly reduce download size and provide a further potential
    102 performance benefit (for example, the hello_world example would only require
    103 downloading a .nexe file that&#8217;s on the order of 30KB, rather than a .nexe
    104 file and several libraries, which are on the order of 1.5MB).</li>
    105 </ul>
    106 <p>Native Client support for dynamic linking and loading is based on glibc. Thus,
    107 <strong>if your Native Client application must dynamically link and load code (e.g.,
    108 due to licensing considerations), we recommend that you use the glibc
    109 library.</strong></p>
    110 <aside class="note">
    111 <p><strong>Notes:</strong></p>
    112 <ul class="small-gap">
    113 <li><strong>None of the above constitutes legal advice, or a description of the legal
    114 obligations you need to fulfill in order to be compliant with the LGPL or
    115 newlib licenses. The above description is only a technical explanation of
    116 the differences between newlib and glibc, and the choice you must make
    117 between the two libraries.</strong></li>
    118 <li>Static linking with glibc is rarely used. Use this feature with caution.</li>
    119 <li>The standard C++ runtime in Native Client is provided by libstdc++; this
    120 library is independent from and layered on top of glibc. Because of
    121 licensing restrictions, libstdc++ must be statically linked for commercial
    122 uses, even if the rest of an application is dynamically linked.</li>
    123 </ul>
    124 
    125 </aside>
    126 </section><section id="sdk-toolchains">
    127 <h3 id="sdk-toolchains">SDK toolchains</h3>
    128 <p>The Native Client SDK contains multiple toolchains, which are differentiated by
    129 <a class="reference internal" href="/native-client/devguide/devcycle/building.html#target-architectures"><em>target architecture</em></a> and C library:</p>
    130 <table border="1" class="docutils">
    131 <colgroup>
    132 </colgroup>
    133 <thead valign="bottom">
    134 <tr class="row-odd"><th class="head">Target architecture</th>
    135 <th class="head">C library</th>
    136 <th class="head">Toolchain directory</th>
    137 </tr>
    138 </thead>
    139 <tbody valign="top">
    140 <tr class="row-even"><td>x86</td>
    141 <td>newlib</td>
    142 <td>toolchain/&lt;platform&gt;_x86_newlib</td>
    143 </tr>
    144 <tr class="row-odd"><td>x86</td>
    145 <td>glibc</td>
    146 <td>toolchain/&lt;platform&gt;_x86_glibc</td>
    147 </tr>
    148 <tr class="row-even"><td>ARM</td>
    149 <td>newlib</td>
    150 <td>toolchain/&lt;platform&gt;_arm_newlib</td>
    151 </tr>
    152 <tr class="row-odd"><td>PNaCl</td>
    153 <td>newlib</td>
    154 <td>toolchain/&lt;platform&gt;_pnacl</td>
    155 </tr>
    156 </tbody>
    157 </table>
    158 <p>In the directories listed above, &lt;platform&gt; is the platform of your development
    159 machine (i.e., win, mac, or linux). For example, in the Windows SDK, the x86
    160 toolchain that uses glibc is in <code>toolchain/win_x86_glibc</code>.</p>
    161 <aside class="note">
    162 <strong>Note:</strong> The ARM and PNaCl toolchains are currently restricted to newlib.
    163 </aside>
    164 <p>To use the glibc library and dynamic linking in your application, you <strong>must</strong>
    165 use a glibc toolchain. (Currently the only glibc toolchain is
    166 <code>&lt;platform&gt;_x86_glibc</code>.) Note that you must build all code in your application
    167 with one toolchain. Code from multiple toolchains cannot be mixed.</p>
    168 </section><section id="specifying-and-delivering-shared-libraries">
    169 <h3 id="specifying-and-delivering-shared-libraries">Specifying and delivering shared libraries</h3>
    170 <p>One significant difference between newlib and glibc applications is that glibc
    171 applications must explicitly list and deploy the shared libraries that they
    172 use.</p>
    173 <p>In a desktop environment, when the user launches a dynamically linked
    174 application, the operating system&#8217;s program loader determines the set of
    175 libraries the application requires by reading explicit inter-module
    176 dependencies from executable file headers, and loads the required libraries
    177 into the address space of the application process. Typically the required
    178 libraries will have been installed on the system as a part of the application&#8217;s
    179 installation process. Often the desktop application developer doesn&#8217;t know or
    180 think about the libraries that are required by an application, as those details
    181 are taken care of by the user&#8217;s operating system.</p>
    182 <p>In the Native Client sandbox, dynamic linking can&#8217;t rely in the same way on the
    183 operating system or the local file system. Instead, the application developer
    184 must identify the set of libraries that are required by an application, list
    185 those libraries in a Native Client <a class="reference internal" href="/native-client/devguide/coding/application-structure.html#manifest-file"><em>manifest file</em></a>, and
    186 deploy the libraries along with the application. Instructions for how to build
    187 a dynamically linked Native Client application, generate a Native Client
    188 manifest (.nmf) file, and deploy an application are provided below.</p>
    189 </section></section><section id="building-a-dynamically-linked-application">
    190 <h2 id="building-a-dynamically-linked-application">Building a dynamically linked application</h2>
    191 <p>Applications built with the glibc toolchain will by dynamically linked by
    192 default. Application that load shared libraries at runtime using <code>dlopen()</code>
    193 must link with the libdl library (<code>-ldl</code>).</p>
    194 <p>Like other gcc-based toolchains building a dynamic library for NaCl is normally
    195 done by linking with the <code>-shared</code> flag and compiling with the <code>-fPIC</code> flag.
    196 The SDK build system will do this automatically when the <code>SO_RULE</code> Makefile
    197 rule is used.</p>
    198 <p>The Native Client SDK includes an example that demonstrates how to build a
    199 shared library, and how to use the <code>dlopen()</code> interface to load that library
    200 at runtime (after the application is already running). Many applications load
    201 and link shared libraries at launch rather than at runtime, and hence do not
    202 use the <code>dlopen()</code> interface. The SDK example is nevertheless instructive, as
    203 it demonstrates how to build Native Client modules (.nexe files) and shared
    204 libraries (.so files) with the x86 glibc toolchain, and how to generate a
    205 Native Client manifest file for glibc applications.</p>
    206 <p>The SDK example, located in <code>examples/tutorial/dlopen</code>, includes three C++
    207 files:</p>
    208 <dl class="docutils">
    209 <dt>eightball.cc</dt>
    210 <dd>This file implements the function <code>Magic8Ball()</code>, which is used to provide
    211 whimsical answers to user questions. This file is compiled into a shared
    212 library called <code>libeightball.so</code>. This library gets included in the
    213 .nmf file and is therefore directly loadable with <code>dlopen()</code>.</dd>
    214 <dt>reverse.cc</dt>
    215 <dd>This file implements the function <code>Reverse()</code>, which returns reversed
    216 copies of strings that are passed to it. This file is compiled into a shared
    217 library called <code>libreverse.so</code>. This library is <strong>not</strong> included in the
    218 .nmf file and is loaded via an http mount using the <a class="reference internal" href="/native-client/devguide/coding/nacl_io.html#nacl-io"><em>nacl_io library</em></a>.</dd>
    219 <dt>dlopen.cc</dt>
    220 <dd>This file implements the Native Client module, which loads the two shared
    221 libraries and handles communcation with with JavaScript. The file is compiled
    222 into a Native Client executable (.nexe).</dd>
    223 </dl>
    224 <p>Run <code>make</code> in the dlopen directory to see the commands the Makefile executes
    225 to build x86 32-bit and 64-bit .nexe and .so files, and to generate a .nmf
    226 file. These commands are described below.</p>
    227 <aside class="note">
    228 <strong>Note:</strong> The Makefiles for most of the examples in the SDK build the
    229 examples using multiple toolchains (x86 newlib, x86 glibc, ARM, and PNaCl).
    230 With a few exceptions (listed in the <a class="reference internal" href="/native-client/sdk/release-notes.html#sdk-release-notes"><em>Release Notes</em></a>), running &#8220;make&#8221; in each example&#8217;s directory builds
    231 multiple versions of the example using the SDK toolchains. The dlopen example
    232 is one of those exceptions  it is only built with the x86 glibc toolchain,
    233 as that is currently the only toolchain that supports glibc and thus dynamic
    234 linking and loading. Take a look at the example Makefiles and the generated
    235 .nmf files for details on how to build dynamically linked applications.
    236 </aside>
    237 </section><section id="generating-a-native-client-manifest-file-for-a-dynamically-linked-application">
    238 <span id="dynamic-loading-manifest"></span><h2 id="generating-a-native-client-manifest-file-for-a-dynamically-linked-application"><span id="dynamic-loading-manifest"></span>Generating a Native Client manifest file for a dynamically linked application</h2>
    239 <p>The Native Client manifest file specifies the name of the executable to run
    240 and must also specify any shared libraries that the application directly
    241 depends on. For indirect dependencies (such as libraries opened via
    242 <code>dlopen()</code>) it is also convenient to list libraries in the manifest file.
    243 However it is possile to load arbitrary shared libraries at runtime that
    244 are not mentioned in the manifest by using the <a class="reference external" href="nacl_io">nacl_io library</a>
    245 to mount a filesystem that contains the shared libraries which will then
    246 allow <code>dlopen()</code> to access them.</p>
    247 <p>In this example we demonstrate both loading directly from via the manifest
    248 file (<code>libeightball.so</code>) and loading indirectly via a http mount
    249 (<code>libreverse.so</code>).</p>
    250 <p>Take a look at the manifest file in the dlopen example to see how
    251 a glibc-style manifest file is structured. (Run <code>make</code> in the dlopen directory to
    252 generate the manifest file if you haven&#8217;t done so already.) Here is an excerpt
    253 from <code>dlopen.nmf</code>:</p>
    254 <pre class="prettyprint">
    255 {
    256   &quot;files&quot;: {
    257     &quot;libeightball.so&quot;: {
    258       &quot;x86-64&quot;: {
    259         &quot;url&quot;: &quot;lib64/libeightball.so&quot;
    260       },
    261       &quot;x86-32&quot;: {
    262         &quot;url&quot;: &quot;lib32/libeightball.so&quot;
    263       }
    264     },
    265     &quot;libstdc++.so.6&quot;: {
    266       &quot;x86-64&quot;: {
    267         &quot;url&quot;: &quot;lib64/libstdc++.so.6&quot;
    268       },
    269       &quot;x86-32&quot;: {
    270         &quot;url&quot;: &quot;lib32/libstdc++.so.6&quot;
    271       }
    272     },
    273     &quot;libppapi_cpp.so&quot;: {
    274       &quot;x86-64&quot;: {
    275         &quot;url&quot;: &quot;lib64/libppapi_cpp.so&quot;
    276       },
    277       &quot;x86-32&quot;: {
    278         &quot;url&quot;: &quot;lib32/libppapi_cpp.so&quot;
    279       }
    280     },
    281 ... etc.
    282 </pre>
    283 <p>In most cases, you can use the <code>create_nmf.py</code> script in the SDK to generate
    284 a manifest file for your application. The script is located in the tools
    285 directory (e.g. <code>pepper_28/tools</code>).</p>
    286 <p>The Makefile in the dlopen example generates the manifest automatically using
    287 the <code>NMF_RULE</code> provided by the SDK build system. Running <code>make V=1</code> will
    288 show the full command line which is used to generate the nmf:</p>
    289 <pre class="prettyprint">
    290 create_nmf.py -o dlopen.nmf glibc/Release/dlopen_x86_32.nexe \
    291    glibc/Release/dlopen_x86_64.nexe glibc/Release/libeightball_x86_32.so \
    292    glibc/Release/libeightball_x86_64.so  -s ./glibc/Release \
    293    -n libeightball_x86_32.so,libeightball.so \
    294    -n libeightball_x86_64.so,libeightball.so
    295 </pre>
    296 <p>Run python <code>create_nmf.py --help</code> to see a full description of the command-line
    297 flags. A few of the important flags are described below.</p>
    298 <dl class="docutils">
    299 <dt><code>-s</code> <em>directory</em></dt>
    300 <dd>use <em>directory</em> to stage libraries (libraries are added to <code>lib32</code> and
    301 <code>lib64</code> subfolders)</dd>
    302 <dt><code>-L</code> <em>directory</em></dt>
    303 <dd>add <em>directory</em> to the library search path. The default search path
    304 already includes the toolchain and SDK libraries directories.</dd>
    305 </dl>
    306 <aside class="note">
    307 <strong>Note:</strong> The <code>create_nmf</code> script can only automatically detect explicit
    308 shared library dependencies (for example, dependencies specified with the -l
    309 flag for the compiler/linker). If you want to include libraries that you
    310 intend to dlopen() at runtime you must explcitly list them in your call to
    311 <code>create_nmf</code>.
    312 </aside>
    313 <p>As an alternative to using <code>create_nmf</code>, it is possible to manually calculate
    314 the list of shared library dependencies using tools such as <code>objdump_</code>.</p>
    315 </section><section id="deploying-a-dynamically-linked-application">
    316 <h2 id="deploying-a-dynamically-linked-application">Deploying a dynamically linked application</h2>
    317 <p>As described above, an application&#8217;s manifest file must explicitly list all the
    318 executable code modules that the application directly depends on, including
    319 modules from the application itself (.nexe and .so files), modules from the
    320 Native Client SDK (e.g., libppapi_cpp.so), and perhaps also modules from
    321 <a class="reference external" href="naclports_">naclport</a> or from <a class="reference external" href="../../community/middleware">middleware systems</a> that
    322 the application uses. You must provide all of those modules as part of the
    323 application deployment process.</p>
    324 <p>As explained in <a class="reference internal" href="/native-client/devguide/distributing.html"><em>Distributing Your Application</em></a>, there are two basic ways to deploy an application:</p>
    325 <ul class="small-gap">
    326 <li><strong>hosted application:</strong> all modules are hosted together on a web server of
    327 your choice</li>
    328 <li><strong>packaged application:</strong> all modules are packaged into one file, hosted in
    329 the Chrome Web Store, and downloaded to the user&#8217;s machine</li>
    330 </ul>
    331 <p>You must deploy all the modules listed in your application&#8217;s manifest file for
    332 either the hosted application or the packaged application case. For hosted
    333 applications, you must upload the modules to your web server. For packaged
    334 applications, you must include the modules in the application&#8217;s Chrome Web
    335 Store .crx file. Modules should use URLs/names that are consistent with those
    336 in the Native Client manifest file, and be named relative to the location of
    337 the manifest file. Remember that some of the libraries named in the manifest
    338 file may be located in directories you specified with the -L option to
    339 <code>create_nmf.py</code>. You are free to rename/rearrange files and directories
    340 referenced by the Native Client manifest file, so long as the modules are
    341 available in the locations indicated by the manifest file. If you move or
    342 rename modules, it may be easier to re-run <code>create_nmf.py</code> to generate a new
    343 manifest file rather than edit the original manifest file. For hosted
    344 applications, you can check for name mismatches during testing by watching the
    345 request log of the web server hosting your test deployment.</p>
    346 </section><section id="opening-a-shared-library-at-runtime">
    347 <h2 id="opening-a-shared-library-at-runtime">Opening a shared library at runtime</h2>
    348 <p>Native Client supports a version of the POSIX standard <code>dlopen()</code> interface
    349 for opening libraries explicitly, after an application is already running.
    350 Calling <code>dlopen()</code> may cause a library download to occur, and automatically
    351 loads all libraries that are required by the named library.</p>
    352 <aside class="note">
    353 <strong>Caution:</strong> Since <code>dlopen()</code> can potentially block, you must initially
    354 call <code>dlopen()</code> off your application&#8217;s main thread. Initial calls to
    355 <code>dlopen()</code> from the main thread will always fail in the current
    356 implementation of Native Client.
    357 </aside>
    358 <p>The best practice for opening libraries with <code>dlopen()</code> is to use a worker
    359 thread to pre-load libraries asynchronously during initialization of your
    360 application, so that the libraries are available when they&#8217;re needed. You can
    361 call <code>dlopen()</code> a second time when you need to use a library &#8211; per the
    362 specification, subsequent calls to <code>dlopen()</code> return a handle to the
    363 previously loaded library. Note that you should only call <code>dlclose()</code> to
    364 close a library when you no longer need the library; otherwise, subsequent
    365 calls to <code>dlopen()</code> could cause the library to be fetched again.</p>
    366 <p>The dlopen example in the SDK demonstrates how to open a shared libraries
    367 at runtime. To reiterate, the example includes three C++ files:</p>
    368 <ul class="small-gap">
    369 <li><code>eightball.cc</code>: this is the shared library that implements the function
    370 <code>Magic8Ball()</code> (this file is compiled into libeightball.so)</li>
    371 <li><code>reverse.cc</code>: this is the shared library that implements the function
    372 <code>Reverse()</code> (this file is compiled into libreverse.so)</li>
    373 <li><code>dlopen.cc</code>: this is the Native Client module that loads the shared libraries
    374 and makes calls to <code>Magic8Ball()</code> and <code>Reverse()</code> in response to requests
    375 from JavaScript.</li>
    376 </ul>
    377 <p>When the Native Client module starts, it kicks off a worker thread that calls
    378 <code>dlopen()</code> to load the two shared libraries. Once the module has a handle to
    379 the library, it fetches the addresses of the <code>Magic8Ball()</code> and <code>Reverse()</code>
    380 functions using <code>dlsym()</code>. When a user types in a query and clicks the &#8216;ASK!&#8217;
    381 button, the module calls <code>Magic8Ball()</code> to generate an answer, and returns
    382 the result to the user. Likewise when the user clicks the &#8216;Reverse&#8217; button
    383 it calls the <code>Reverse()</code> function to reverse the string.</p>
    384 </section><section id="troubleshooting">
    385 <h2 id="troubleshooting">Troubleshooting</h2>
    386 <p>If your .nexe isn&#8217;t loading, the best place to look for information that can
    387 help you troubleshoot the JavaScript console and standard output from Chrome.
    388 See <a class="reference internal" href="/native-client/devguide/devcycle/debugging.html#devcycle-debugging"><em>Debugging</em></a> for more information.</p>
    389 <p>Here are a few common error messages and explanations of what they mean:</p>
    390 <dl class="docutils">
    391 <dt><strong>/main.nexe: error while loading shared libraries: /main.nexe: failed to allocate code and data space for executable</strong></dt>
    392 <dd>The .nexe may not have been compiled correctly (e.g., the .nexe may be
    393 statically linked). Try cleaning and recompiling with the glibc toolchain.</dd>
    394 <dt><strong>/main.nexe: error while loading shared libraries: libpthread.so.xxxx: cannot open shared object file: Permission denied</strong></dt>
    395 <dd>(xxxx is a version number, for example, 5055067a.) This error can result from
    396 having the wrong path in the .nmf file. Double-check that the path in the
    397 .nmf file is correct.</dd>
    398 <dt><strong>/main.nexe: error while loading shared libraries: /main.nexe: cannot open shared object file: No such file or directory</strong></dt>
    399 <dd>If there are no obvious problems with your main.nexe entry in the .nmf file,
    400 check where main.nexe is being requested from. Use Chrome&#8217;s Developer Tools:
    401 Click the menu icon <img alt="menu-icon" src="/native-client/images/menu-icon.png" />, select Tools &gt; Developer Tools, click the
    402 Network tab, and look at the path in the Name column.</dd>
    403 <dt><strong>NaCl module load failed: ELF executable text/rodata segment has wrong starting address</strong></dt>
    404 <dd>This error happens when using a newlib-style .nmf file instead of a
    405 glibc-style .nmf file. Make sure you build your application with the glic
    406 toolchain, and use the create_nmf.py script to generate your .nmf file.</dd>
    407 <dt><strong>NativeClient: NaCl module load failed: Nexe crashed during startup</strong></dt>
    408 <dd>This error message indicates that a module crashed while being loaded. You
    409 can determine which module crashed by looking at the Network tab in Chrome&#8217;s
    410 Developer Tools (see above). The module that crashed will be the last one
    411 that was loaded.</dd>
    412 <dt><strong>/lib/main.nexe: error while loading shared libraries: /lib/main.nexe: only ET_DYN and ET_EXEC can be loaded</strong></dt>
    413 <dd>This error message indicates that there is an error with the .so files listed
    414 in the .nmf file &#8211; either the files are the wrong type or kind, or an
    415 expected library is missing.</dd>
    416 <dt><strong>undefined reference to &#8216;dlopen&#8217; collect2: ld returned 1 exit status</strong></dt>
    417 <dd>This is a linker ordering problem that usually results from improper ordering
    418 of command line flags when linking. Reconfigure your command line string to
    419 list libraries after the -o flag.</dd>
    420 </dl>
    421 </section></section>
    422 
    423 {{/partials.standard_nacl_article}}
    424