• Victor Costan's avatar
    sqlite: Prefix SQLite API methods with chrome_. · 3d8ec487
    Victor Costan authored
    In component builds, SQLite's API methods are exported from the
    chromium_sqlite component, which means they are visible to the dynamic
    library loader. This opens up the following possibilities:
    
    1) A system library calls into our SQLite instead of calling into the
       system's SQLite library which it was built against. The patches in
       our SQLite version lead to different behavior from the system's
       SQLite, which can cause subtle failures. This happens if the dynamic
       library loader resolves the system library's symbol imports with our
       SQLite's exported symbols.
    2) A system library loads the system SQLite, and we end up calling into
       it, instead of calling into our version of SQLite. This happens if
       the dynamic library loader resolves our symbol imports with the
       system's SQLite library.
    
    Both possibilities above lead to the possibility that the component
    build will behave differently from the release build, in subtle and
    potentially non-deterministic ways. This is not a purely academic
    concern. https://crbug.com/807487 happened because we use NSS on Linux,
    and NSS invokes SQLite via a complex plugin system. On non-component builds,
    NSS (a system library) loads and uses the system version of SQLite. On
    component builds, NSS ends up using our SQLite.
    
    This CL fixes the problem by adding a chrome_ prefix to all the symbols
    exported from SQLite3. In C++ libraries, namespaces can make prefixing
    easy. Unfortunately, SQLite is a C library, so the prefixing is fairly
    heavy-handed. A high-level overview of the approach follows:
    
    * An extract_sqlite_api Python script reads SQLite's header, extracts
      the names of all exported symbols, and writes a header file consisting
      of renaming preprocessor macros, e.g.
          #define sqlite3_init chrome_sqlite3_init
      David Benjamin <davidben@chromium.org> designed the approach and wrote
      the original version of the script.
    * The script that we use to generate SQLite's amalgamation now also
      invokes the extract_sqlite_api script described above, and saves the
      output to amalgamation/rename_exports.h.
    * The SQLite component exposes an sqlite3.h header that must be used by
      all SQLite3 users in Chromium. This header now #includes
      rename_exports.h (containing the renaming preprocessor macros) before
      #including amalgamation/sqlite3.h.
    * sqlite3.c (the main output of the amalgamation process) does not
      #include "sqlite3.h". However, in order to facilitate autoconf builds,
      it does #include a "config.h", if a certain preprocessor define
      exists. We abuse that define to have sqlite.c always load config.h,
      and have config.h load our rename_exports.h.
    
    This CL also adds a PRESUBMIT.py that runs unit tests for the
    extract_sqlite_api Python script, which ensures that the script will not
    break accidentally. Both the unit tests and the PRESUBIMT script are
    inspired from //tools/vim.
    
    Bug: 807093, 807487
    Change-Id: If3868ba119ffd4ccbb06d1a6fcd4cc2ecd9ef2ae
    Reviewed-on: https://chromium-review.googlesource.com/898549Reviewed-by: default avatarChris Mumford <cmumford@chromium.org>
    Commit-Queue: Victor Costan <pwnall@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#534843}
    3d8ec487
README.md 281 Bytes