-
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:
Chris Mumford <cmumford@chromium.org> Commit-Queue: Victor Costan <pwnall@chromium.org> Cr-Commit-Position: refs/heads/master@{#534843}
3d8ec487