-
Notifications
You must be signed in to change notification settings - Fork 852
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Hide extension symbols by default on Unix platforms
On platforms using libraries and executables in ELF format (e.g., Linux), exported symbols can collide. If a symbol (e.g., a function) is already available, loading a module with a function that has the exact same name will cause the newly loaded library to use the already existing function instead of the one in the new module. Unfortunately, GCC and Clang exports all symbols by default. To avoid symbol collisions, this change compiles the extension with `-fvisibility=hidden` on Unix platforms, which means a symbol isn't exported unless explicitly specified. Note that symbols are not exported by default on Windows. For GCC and Clang, a symbol can be exported by annotating a function or variable with `__attribute__ ((visibility ("default")))`. This is done transparently using our custom `TS_FUNCTION_INFO_V1` macro. Note that functions exported with that macro might still collide with existing symbols so they should have proper name prefixes that make collisions unlikely. A test for conflicting symbols runs in Debug configuration. When compiled in Debug configuration, code with an identically named function is added to both the loader and then versioned extension, although the functions return different outputs. The functions are called from both the loader and the versioned extension and the output should contain different module names if no conflict. The test fails on Linux if not compiled with -fvisibility=hidden.
- Loading branch information
Showing
13 changed files
with
174 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#ifndef TIMESCALEDB_EXPORT_H | ||
#define TIMESCALEDB_EXPORT_H | ||
|
||
#include <postgres.h> | ||
|
||
/* Definitions for symbol exports */ | ||
|
||
#define TS_CAT(x,y) x ## y | ||
#define TS_EMPTY(x) (TS_CAT(x, 87628) == 87628) | ||
|
||
#if defined(_WIN32) && !defined(WIN32) | ||
#define WIN32 | ||
#endif | ||
|
||
#if !defined(WIN32) && !defined(__CYGWIN__) | ||
#if __GNUC__ >= 4 | ||
#if defined(PGDLLEXPORT) | ||
#if TS_EMPTY(PGDLLEXPORT) | ||
/* PGDLLEXPORT is defined but empty. We can safely undef it. */ | ||
#undef PGDLLEXPORT | ||
#else | ||
#error "PGDLLEXPORT is already defined" | ||
#endif | ||
#endif /* defined(PGDLLEXPORT) */ | ||
#define PGDLLEXPORT __attribute__ ((visibility ("default"))) | ||
#else | ||
#error "Unsupported GNUC version" | ||
#endif /* __GNUC__ */ | ||
#endif | ||
|
||
#define TS_FUNCTION_INFO_V1(fn) \ | ||
PGDLLEXPORT Datum fn(PG_FUNCTION_ARGS); \ | ||
PG_FUNCTION_INFO_V1(fn) | ||
|
||
#endif /* TIMESCALEDB_EXPORT_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
\c single :ROLE_SUPERUSER | ||
-- Test for symbol conflicts between the loader module and the | ||
-- versioned extension module. | ||
-- This test fails on, e.g. Linux, unless compiled with -fvisibility=hidden | ||
CREATE OR REPLACE FUNCTION hello_loader() RETURNS TEXT | ||
AS 'timescaledb', 'loader_hello' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT; | ||
SELECT hello_loader(); | ||
hello_loader | ||
------------------- | ||
hello from loader | ||
(1 row) | ||
|
||
CREATE OR REPLACE FUNCTION hello_timescaledb() RETURNS TEXT | ||
AS :MODULE_PATHNAME, 'timescaledb_hello' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT; | ||
-- This calls an internal function with a conflicting name in the loader | ||
SELECT hello_loader(); | ||
hello_loader | ||
------------------- | ||
hello from loader | ||
(1 row) | ||
|
||
-- This calls the identically named internal function in the versioned extension | ||
SELECT hello_timescaledb(); | ||
hello_timescaledb | ||
------------------------ | ||
hello from timescaledb | ||
(1 row) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
\c single :ROLE_SUPERUSER | ||
|
||
-- Test for symbol conflicts between the loader module and the | ||
-- versioned extension module. | ||
-- This test fails on, e.g. Linux, unless compiled with -fvisibility=hidden | ||
CREATE OR REPLACE FUNCTION hello_loader() RETURNS TEXT | ||
AS 'timescaledb', 'loader_hello' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT; | ||
|
||
SELECT hello_loader(); | ||
|
||
CREATE OR REPLACE FUNCTION hello_timescaledb() RETURNS TEXT | ||
AS :MODULE_PATHNAME, 'timescaledb_hello' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT; | ||
|
||
-- This calls an internal function with a conflicting name in the loader | ||
SELECT hello_loader(); | ||
-- This calls the identically named internal function in the versioned extension | ||
SELECT hello_timescaledb(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#include <postgres.h> | ||
#include <utils/builtins.h> | ||
#include <fmgr.h> | ||
#include "../../src/compat.h" | ||
|
||
#define STR_EXPAND(x) #x | ||
#define STR(x) STR_EXPAND(x) | ||
|
||
#define FUNC_EXPAND(prefix, name) prefix##_##name | ||
#define FUNC(prefix, name) FUNC_EXPAND(prefix, name) | ||
|
||
/* Function with conflicting name when included in multiple modules */ | ||
extern const char *test_symbol_conflict(void); | ||
|
||
const char * | ||
test_symbol_conflict(void) | ||
{ | ||
return "hello from " STR(MODULE_NAME); | ||
} | ||
|
||
TS_FUNCTION_INFO_V1(FUNC(MODULE_NAME, hello)); | ||
|
||
Datum | ||
FUNC(MODULE_NAME, hello) (PG_FUNCTION_ARGS) | ||
{ | ||
PG_RETURN_TEXT_P(cstring_to_text(test_symbol_conflict())); | ||
} |