netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] libmnl: Failed to build with clang, incompatible EXPORT_SYMBOL(x) macro
@ 2015-09-25  4:07 Neutron Soutmun
  2015-09-30 22:12 ` Pablo Neira Ayuso
  0 siblings, 1 reply; 8+ messages in thread
From: Neutron Soutmun @ 2015-09-25  4:07 UTC (permalink / raw)
  To: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 38717 bytes --]

The EXPORT_SYMBOL(x) macro causes clang compile error and warning
messges:
  error,   "note: previous definition is here"
  warning, "warning: attribute declaration must precede definition
            [-Wignored-attributes]"
  See: [1]

This proposed patch has been prepared to fix this error which make the
EXPORT_SYMBOL macro define a precede definition of an attribute
declaration. This approach is both compatible with gcc and clang.

[1] http://clang.debian.net/logs/2014-09-03/libmnl_1.0.3-5_unstable_clang.log

Signed-off-by: Neutron Soutmun <neo.neutron@gmail.com>
---
 doxygen.cfg.in |   8 +--
 src/attr.c     | 162 ++++++++++++++++++++++++++-------------------------------
 src/callback.c |  12 ++---
 src/internal.h |   3 +-
 src/nlmsg.c    |  76 +++++++++++++--------------
 src/socket.c   |  42 +++++++--------
 6 files changed, 138 insertions(+), 165 deletions(-)

diff --git a/doxygen.cfg.in b/doxygen.cfg.in
index ee8fdfa..6fc842c 100644
--- a/doxygen.cfg.in
+++ b/doxygen.cfg.in
@@ -72,7 +72,7 @@ RECURSIVE              = YES
 EXCLUDE                = 
 EXCLUDE_SYMLINKS       = NO
 EXCLUDE_PATTERNS       = */.git/* .*.d
-EXCLUDE_SYMBOLS        = EXPORT_SYMBOL
+EXCLUDE_SYMBOLS        =
 EXAMPLE_PATH           = 
 EXAMPLE_PATTERNS       = 
 EXAMPLE_RECURSIVE      = NO
@@ -144,12 +144,12 @@ PERLMOD_LATEX          = NO
 PERLMOD_PRETTY         = YES
 PERLMOD_MAKEVAR_PREFIX = 
 ENABLE_PREPROCESSING   = YES
-MACRO_EXPANSION        = NO
-EXPAND_ONLY_PREDEF     = NO
+MACRO_EXPANSION        = YES
+EXPAND_ONLY_PREDEF     = YES
 SEARCH_INCLUDES        = YES
 INCLUDE_PATH           = 
 INCLUDE_FILE_PATTERNS  = 
-PREDEFINED             = 
+PREDEFINED             = EXPORT_SYMBOL=
 EXPAND_AS_DEFINED      = 
 SKIP_FUNCTION_MACROS   = YES
 TAGFILES               = 
diff --git a/src/attr.c b/src/attr.c
index c551d0b..7dcb756 100644
--- a/src/attr.c
+++ b/src/attr.c
@@ -35,11 +35,11 @@
  *
  * This function returns the attribute type.
  */
-uint16_t mnl_attr_get_type(const struct nlattr *attr)
+EXPORT_SYMBOL uint16_t
+mnl_attr_get_type(const struct nlattr *attr)
 {
 	return attr->nla_type & NLA_TYPE_MASK;
 }
-EXPORT_SYMBOL(mnl_attr_get_type);
 
 /**
  * mnl_attr_get_len - get length of netlink attribute
@@ -48,11 +48,11 @@ EXPORT_SYMBOL(mnl_attr_get_type);
  * This function returns the attribute length that is the attribute header
  * plus the attribute payload.
  */
-uint16_t mnl_attr_get_len(const struct nlattr *attr)
+EXPORT_SYMBOL uint16_t
+mnl_attr_get_len(const struct nlattr *attr)
 {
 	return attr->nla_len;
 }
-EXPORT_SYMBOL(mnl_attr_get_len);
 
 /**
  * mnl_attr_get_payload_len - get the attribute payload-value length
@@ -60,11 +60,11 @@ EXPORT_SYMBOL(mnl_attr_get_len);
  *
  * This function returns the attribute payload-value length.
  */
-uint16_t mnl_attr_get_payload_len(const struct nlattr *attr)
+EXPORT_SYMBOL uint16_t
+mnl_attr_get_payload_len(const struct nlattr *attr)
 {
 	return attr->nla_len - MNL_ATTR_HDRLEN;
 }
-EXPORT_SYMBOL(mnl_attr_get_payload_len);
 
 /**
  * mnl_attr_get_payload - get pointer to the attribute payload
@@ -72,11 +72,11 @@ EXPORT_SYMBOL(mnl_attr_get_payload_len);
  *
  * This function return a pointer to the attribute payload.
  */
-void *mnl_attr_get_payload(const struct nlattr *attr)
+EXPORT_SYMBOL void *
+mnl_attr_get_payload(const struct nlattr *attr)
 {
 	return (void *)attr + MNL_ATTR_HDRLEN;
 }
-EXPORT_SYMBOL(mnl_attr_get_payload);
 
 /**
  * mnl_attr_ok - check if there is room for an attribute in a buffer
@@ -94,13 +94,13 @@ EXPORT_SYMBOL(mnl_attr_get_payload);
  * The len parameter may be negative in the case of malformed messages during
  * attribute iteration, that is why we use a signed integer.
  */
-bool mnl_attr_ok(const struct nlattr *attr, int len)
+EXPORT_SYMBOL bool
+mnl_attr_ok(const struct nlattr *attr, int len)
 {
 	return len >= (int)sizeof(struct nlattr) &&
 	       attr->nla_len >= sizeof(struct nlattr) &&
 	       (int)attr->nla_len <= len;
 }
-EXPORT_SYMBOL(mnl_attr_ok);
 
 /**
  * mnl_attr_next - get the next attribute in the payload of a netlink message
@@ -110,11 +110,11 @@ EXPORT_SYMBOL(mnl_attr_ok);
  * as parameter. You have to use mnl_attr_ok() to ensure that the next
  * attribute is valid.
  */
-struct nlattr *mnl_attr_next(const struct nlattr *attr)
+EXPORT_SYMBOL struct nlattr *
+mnl_attr_next(const struct nlattr *attr)
 {
 	return (struct nlattr *)((void *)attr + MNL_ALIGN(attr->nla_len));
 }
-EXPORT_SYMBOL(mnl_attr_next);
 
 /**
  * mnl_attr_type_valid - check if the attribute type is valid
@@ -130,7 +130,8 @@ EXPORT_SYMBOL(mnl_attr_next);
  * This leads to backward compatibility breakages in user-space. Better check
  * if you support an attribute, if not, skip it.
  */
-int mnl_attr_type_valid(const struct nlattr *attr, uint16_t max)
+EXPORT_SYMBOL int
+mnl_attr_type_valid(const struct nlattr *attr, uint16_t max)
 {
 	if (mnl_attr_get_type(attr) > max) {
 		errno = EOPNOTSUPP;
@@ -138,7 +139,6 @@ int mnl_attr_type_valid(const struct nlattr *attr, uint16_t max)
 	}
 	return 1;
 }
-EXPORT_SYMBOL(mnl_attr_type_valid);
 
 static int __mnl_attr_validate(const struct nlattr *attr,
 			       enum mnl_attr_data_type type, size_t exp_len)
@@ -211,7 +211,8 @@ static const size_t mnl_attr_data_type_len[MNL_TYPE_MAX] = {
  * integers (u8, u16, u32 and u64) have enough room for them. This function
  * returns -1 in case of error, and errno is explicitly set.
  */
-int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type)
+EXPORT_SYMBOL int
+mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type)
 {
 	int exp_len;
 
@@ -222,7 +223,6 @@ int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type)
 	exp_len = mnl_attr_data_type_len[type];
 	return __mnl_attr_validate(attr, type, exp_len);
 }
-EXPORT_SYMBOL(mnl_attr_validate);
 
 /**
  * mnl_attr_validate2 - validate netlink attribute (extended version)
@@ -234,9 +234,9 @@ EXPORT_SYMBOL(mnl_attr_validate);
  * whose size is variable. If the size of the attribute is not what we expect,
  * this functions returns -1 and errno is explicitly set.
  */
-int
+EXPORT_SYMBOL int
 mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type,
-		   size_t exp_len)
+                   size_t exp_len)
 {
 	if (type >= MNL_TYPE_MAX) {
 		errno = EINVAL;
@@ -244,7 +244,6 @@ mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type,
 	}
 	return __mnl_attr_validate(attr, type, exp_len);
 }
-EXPORT_SYMBOL(mnl_attr_validate2);
 
 /**
  * mnl_attr_parse - parse attributes
@@ -261,9 +260,9 @@ EXPORT_SYMBOL(mnl_attr_validate2);
  * This function propagates the return value of the callback, which can be
  * MNL_CB_ERROR, MNL_CB_OK or MNL_CB_STOP.
  */
-int
+EXPORT_SYMBOL int
 mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset,
-	       mnl_attr_cb_t cb, void *data)
+               mnl_attr_cb_t cb, void *data)
 {
 	int ret = MNL_CB_OK;
 	const struct nlattr *attr;
@@ -273,7 +272,6 @@ mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset,
 			return ret;
 	return ret;
 }
-EXPORT_SYMBOL(mnl_attr_parse);
 
 /**
  * mnl_attr_parse_nested - parse attributes inside a nest
@@ -289,9 +287,8 @@ EXPORT_SYMBOL(mnl_attr_parse);
  * This function propagates the return value of the callback, which can be
  * MNL_CB_ERROR, MNL_CB_OK or MNL_CB_STOP.
  */
-int
-mnl_attr_parse_nested(const struct nlattr *nested, mnl_attr_cb_t cb,
-		      void *data)
+EXPORT_SYMBOL int
+mnl_attr_parse_nested(const struct nlattr *nested, mnl_attr_cb_t cb, void *data)
 {
 	int ret = MNL_CB_OK;
 	const struct nlattr *attr;
@@ -301,7 +298,6 @@ mnl_attr_parse_nested(const struct nlattr *nested, mnl_attr_cb_t cb,
 			return ret;
 	return ret;
 }
-EXPORT_SYMBOL(mnl_attr_parse_nested);
 
 /**
  * mnl_attr_parse_payload - parse attributes in payload of Netlink message
@@ -322,9 +318,9 @@ EXPORT_SYMBOL(mnl_attr_parse_nested);
  * This function propagates the return value of the callback, which can be
  * MNL_CB_ERROR, MNL_CB_OK or MNL_CB_STOP.
  */
-int
+EXPORT_SYMBOL int
 mnl_attr_parse_payload(const void *payload, size_t payload_len,
-		       mnl_attr_cb_t cb, void *data)
+                       mnl_attr_cb_t cb, void *data)
 {
 	int ret = MNL_CB_OK;
 	const struct nlattr *attr;
@@ -334,7 +330,6 @@ mnl_attr_parse_payload(const void *payload, size_t payload_len,
 			return ret;
 	return ret;
 }
-EXPORT_SYMBOL(mnl_attr_parse_payload);
 
 /**
  * mnl_attr_get_u8 - returns 8-bit unsigned integer attribute payload
@@ -342,11 +337,11 @@ EXPORT_SYMBOL(mnl_attr_parse_payload);
  *
  * This function returns the 8-bit value of the attribute payload.
  */
-uint8_t mnl_attr_get_u8(const struct nlattr *attr)
+EXPORT_SYMBOL uint8_t
+mnl_attr_get_u8(const struct nlattr *attr)
 {
 	return *((uint8_t *)mnl_attr_get_payload(attr));
 }
-EXPORT_SYMBOL(mnl_attr_get_u8);
 
 /**
  * mnl_attr_get_u16 - returns 16-bit unsigned integer attribute payload
@@ -354,11 +349,11 @@ EXPORT_SYMBOL(mnl_attr_get_u8);
  *
  * This function returns the 16-bit value of the attribute payload.
  */
-uint16_t mnl_attr_get_u16(const struct nlattr *attr)
+EXPORT_SYMBOL uint16_t
+mnl_attr_get_u16(const struct nlattr *attr)
 {
 	return *((uint16_t *)mnl_attr_get_payload(attr));
 }
-EXPORT_SYMBOL(mnl_attr_get_u16);
 
 /**
  * mnl_attr_get_u32 - returns 32-bit unsigned integer attribute payload
@@ -366,11 +361,11 @@ EXPORT_SYMBOL(mnl_attr_get_u16);
  *
  * This function returns the 32-bit value of the attribute payload.
  */
-uint32_t mnl_attr_get_u32(const struct nlattr *attr)
+EXPORT_SYMBOL uint32_t
+mnl_attr_get_u32(const struct nlattr *attr)
 {
 	return *((uint32_t *)mnl_attr_get_payload(attr));
 }
-EXPORT_SYMBOL(mnl_attr_get_u32);
 
 /**
  * mnl_attr_get_u64 - returns 64-bit unsigned integer attribute.
@@ -380,13 +375,13 @@ EXPORT_SYMBOL(mnl_attr_get_u32);
  * function is align-safe, since accessing 64-bit Netlink attributes is a
  * common source of alignment issues.
  */
-uint64_t mnl_attr_get_u64(const struct nlattr *attr)
+EXPORT_SYMBOL uint64_t
+mnl_attr_get_u64(const struct nlattr *attr)
 {
 	uint64_t tmp;
 	memcpy(&tmp, mnl_attr_get_payload(attr), sizeof(tmp));
 	return tmp;
 }
-EXPORT_SYMBOL(mnl_attr_get_u64);
 
 /**
  * mnl_attr_get_str - returns pointer to string attribute.
@@ -394,11 +389,11 @@ EXPORT_SYMBOL(mnl_attr_get_u64);
  *
  * This function returns the payload of string attribute value.
  */
-const char *mnl_attr_get_str(const struct nlattr *attr)
+EXPORT_SYMBOL const char *
+mnl_attr_get_str(const struct nlattr *attr)
 {
 	return mnl_attr_get_payload(attr);
 }
-EXPORT_SYMBOL(mnl_attr_get_str);
 
 /**
  * mnl_attr_put - add an attribute to netlink message
@@ -410,7 +405,7 @@ EXPORT_SYMBOL(mnl_attr_get_str);
  * This function updates the length field of the Netlink message (nlmsg_len)
  * by adding the size (header + payload) of the new attribute.
  */
-void
+EXPORT_SYMBOL void
 mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
 {
 	struct nlattr *attr = mnl_nlmsg_get_payload_tail(nlh);
@@ -421,7 +416,6 @@ mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
 	memcpy(mnl_attr_get_payload(attr), data, len);
 	nlh->nlmsg_len += MNL_ALIGN(payload_len);
 }
-EXPORT_SYMBOL(mnl_attr_put);
 
 /**
  * mnl_attr_put_u8 - add 8-bit unsigned integer attribute to netlink message
@@ -432,11 +426,11 @@ EXPORT_SYMBOL(mnl_attr_put);
  * This function updates the length field of the Netlink message (nlmsg_len)
  * by adding the size (header + payload) of the new attribute.
  */
-void mnl_attr_put_u8(struct nlmsghdr *nlh, uint16_t type, uint8_t data)
+EXPORT_SYMBOL void
+mnl_attr_put_u8(struct nlmsghdr *nlh, uint16_t type, uint8_t data)
 {
 	mnl_attr_put(nlh, type, sizeof(uint8_t), &data);
 }
-EXPORT_SYMBOL(mnl_attr_put_u8);
 
 /**
  * mnl_attr_put_u16 - add 16-bit unsigned integer attribute to netlink message
@@ -447,11 +441,11 @@ EXPORT_SYMBOL(mnl_attr_put_u8);
  * This function updates the length field of the Netlink message (nlmsg_len)
  * by adding the size (header + payload) of the new attribute.
  */
-void mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type, uint16_t data)
+EXPORT_SYMBOL void
+mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type, uint16_t data)
 {
 	mnl_attr_put(nlh, type, sizeof(uint16_t), &data);
 }
-EXPORT_SYMBOL(mnl_attr_put_u16);
 
 /**
  * mnl_attr_put_u32 - add 32-bit unsigned integer attribute to netlink message
@@ -462,11 +456,11 @@ EXPORT_SYMBOL(mnl_attr_put_u16);
  * This function updates the length field of the Netlink message (nlmsg_len)
  * by adding the size (header + payload) of the new attribute.
  */
-void mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type, uint32_t data)
+EXPORT_SYMBOL void
+mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type, uint32_t data)
 {
 	mnl_attr_put(nlh, type, sizeof(uint32_t), &data);
 }
-EXPORT_SYMBOL(mnl_attr_put_u32);
 
 /**
  * mnl_attr_put_u64 - add 64-bit unsigned integer attribute to netlink message
@@ -477,11 +471,11 @@ EXPORT_SYMBOL(mnl_attr_put_u32);
  * This function updates the length field of the Netlink message (nlmsg_len)
  * by adding the size (header + payload) of the new attribute.
  */
-void mnl_attr_put_u64(struct nlmsghdr *nlh, uint16_t type, uint64_t data)
+EXPORT_SYMBOL void
+mnl_attr_put_u64(struct nlmsghdr *nlh, uint16_t type, uint64_t data)
 {
 	mnl_attr_put(nlh, type, sizeof(uint64_t), &data);
 }
-EXPORT_SYMBOL(mnl_attr_put_u64);
 
 /**
  * mnl_attr_put_str - add string attribute to netlink message
@@ -492,11 +486,11 @@ EXPORT_SYMBOL(mnl_attr_put_u64);
  * This function updates the length field of the Netlink message (nlmsg_len)
  * by adding the size (header + payload) of the new attribute.
  */
-void mnl_attr_put_str(struct nlmsghdr *nlh, uint16_t type, const char *data)
+EXPORT_SYMBOL void
+mnl_attr_put_str(struct nlmsghdr *nlh, uint16_t type, const char *data)
 {
 	mnl_attr_put(nlh, type, strlen(data), data);
 }
-EXPORT_SYMBOL(mnl_attr_put_str);
 
 /**
  * mnl_attr_put_strz - add string attribute to netlink message
@@ -510,11 +504,11 @@ EXPORT_SYMBOL(mnl_attr_put_str);
  * This function updates the length field of the Netlink message (nlmsg_len)
  * by adding the size (header + payload) of the new attribute.
  */
-void mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data)
+EXPORT_SYMBOL void
+mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data)
 {
 	mnl_attr_put(nlh, type, strlen(data)+1, data);
 }
-EXPORT_SYMBOL(mnl_attr_put_strz);
 
 /**
  * mnl_attr_nest_start - start an attribute nest
@@ -525,7 +519,8 @@ EXPORT_SYMBOL(mnl_attr_put_strz);
  * an attribute nest. This function always returns a valid pointer to the
  * beginning of the nest.
  */
-struct nlattr *mnl_attr_nest_start(struct nlmsghdr *nlh, uint16_t type)
+EXPORT_SYMBOL struct nlattr *
+mnl_attr_nest_start(struct nlmsghdr *nlh, uint16_t type)
 {
 	struct nlattr *start = mnl_nlmsg_get_payload_tail(nlh);
 
@@ -535,7 +530,6 @@ struct nlattr *mnl_attr_nest_start(struct nlmsghdr *nlh, uint16_t type)
 
 	return start;
 }
-EXPORT_SYMBOL(mnl_attr_nest_start);
 
 /**
  * mnl_attr_put_check - add an attribute to netlink message
@@ -551,16 +545,15 @@ EXPORT_SYMBOL(mnl_attr_nest_start);
  * attribute. The function returns true if the attribute could be added
  * to the message, otherwise false is returned.
  */
-bool
-mnl_attr_put_check(struct nlmsghdr *nlh, size_t buflen,
-		   uint16_t type, size_t len, const void *data)
+EXPORT_SYMBOL bool
+mnl_attr_put_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type,
+                   size_t len, const void *data)
 {
 	if (nlh->nlmsg_len + MNL_ATTR_HDRLEN + MNL_ALIGN(len) > buflen)
 		return false;
 	mnl_attr_put(nlh, type, len, data);
 	return true;
 }
-EXPORT_SYMBOL(mnl_attr_put_check);
 
 /**
  * mnl_attr_put_u8_check - add 8-bit unsigned int attribute to netlink message
@@ -575,13 +568,12 @@ EXPORT_SYMBOL(mnl_attr_put_check);
  * attribute. The function returns true if the attribute could be added
  * to the message, otherwise false is returned.
  */
-bool
-mnl_attr_put_u8_check(struct nlmsghdr *nlh, size_t buflen,
-		      uint16_t type, uint8_t data)
+EXPORT_SYMBOL bool
+mnl_attr_put_u8_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type,
+                      uint8_t data)
 {
 	return mnl_attr_put_check(nlh, buflen, type, sizeof(uint8_t), &data);
 }
-EXPORT_SYMBOL(mnl_attr_put_u8_check);
 
 /**
  * mnl_attr_put_u16_check - add 16-bit unsigned int attribute to netlink message
@@ -598,13 +590,12 @@ EXPORT_SYMBOL(mnl_attr_put_u8_check);
  * This function updates the length field of the Netlink message (nlmsg_len)
  * by adding the size (header + payload) of the new attribute.
  */
-bool
-mnl_attr_put_u16_check(struct nlmsghdr *nlh, size_t buflen,
-		       uint16_t type, uint16_t data)
+EXPORT_SYMBOL bool
+mnl_attr_put_u16_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type,
+                       uint16_t data)
 {
 	return mnl_attr_put_check(nlh, buflen, type, sizeof(uint16_t), &data);
 }
-EXPORT_SYMBOL(mnl_attr_put_u16_check);
 
 /**
  * mnl_attr_put_u32_check - add 32-bit unsigned int attribute to netlink message
@@ -621,13 +612,12 @@ EXPORT_SYMBOL(mnl_attr_put_u16_check);
  * This function updates the length field of the Netlink message (nlmsg_len)
  * by adding the size (header + payload) of the new attribute.
  */
-bool
-mnl_attr_put_u32_check(struct nlmsghdr *nlh, size_t buflen,
-		       uint16_t type, uint32_t data)
+EXPORT_SYMBOL bool
+mnl_attr_put_u32_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type,
+                       uint32_t data)
 {
 	return mnl_attr_put_check(nlh, buflen, type, sizeof(uint32_t), &data);
 }
-EXPORT_SYMBOL(mnl_attr_put_u32_check);
 
 /**
  * mnl_attr_put_u64_check - add 64-bit unsigned int attribute to netlink message
@@ -644,13 +634,12 @@ EXPORT_SYMBOL(mnl_attr_put_u32_check);
  * This function updates the length field of the Netlink message (nlmsg_len)
  * by adding the size (header + payload) of the new attribute.
  */
-bool
-mnl_attr_put_u64_check(struct nlmsghdr *nlh, size_t buflen,
-		       uint16_t type, uint64_t data)
+EXPORT_SYMBOL bool
+mnl_attr_put_u64_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type,
+                       uint64_t data)
 {
 	return mnl_attr_put_check(nlh, buflen, type, sizeof(uint64_t), &data);
 }
-EXPORT_SYMBOL(mnl_attr_put_u64_check);
 
 /**
  * mnl_attr_put_str_check - add string attribute to netlink message
@@ -667,13 +656,12 @@ EXPORT_SYMBOL(mnl_attr_put_u64_check);
  * This function updates the length field of the Netlink message (nlmsg_len)
  * by adding the size (header + payload) of the new attribute.
  */
-bool
-mnl_attr_put_str_check(struct nlmsghdr *nlh, size_t buflen,
-		       uint16_t type, const char *data)
+EXPORT_SYMBOL bool
+mnl_attr_put_str_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type,
+                       const char *data)
 {
 	return mnl_attr_put_check(nlh, buflen, type, strlen(data), data);
 }
-EXPORT_SYMBOL(mnl_attr_put_str_check);
 
 /**
  * mnl_attr_put_strz_check - add string attribute to netlink message
@@ -691,13 +679,12 @@ EXPORT_SYMBOL(mnl_attr_put_str_check);
  * attribute. The function returns true if the attribute could be added
  * to the message, otherwise false is returned.
  */
-bool
-mnl_attr_put_strz_check(struct nlmsghdr *nlh, size_t buflen,
-			uint16_t type, const char *data)
+EXPORT_SYMBOL bool
+mnl_attr_put_strz_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type,
+                        const char *data)
 {
 	return mnl_attr_put_check(nlh, buflen, type, strlen(data)+1, data);
 }
-EXPORT_SYMBOL(mnl_attr_put_strz_check);
 
 /**
  * mnl_attr_nest_start_check - start an attribute nest
@@ -709,14 +696,13 @@ EXPORT_SYMBOL(mnl_attr_put_strz_check);
  * an attribute nest. If the nested attribute cannot be added then NULL,
  * otherwise valid pointer to the beginning of the nest is returned.
  */
-struct nlattr *
+EXPORT_SYMBOL struct nlattr *
 mnl_attr_nest_start_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type)
 {
 	if (nlh->nlmsg_len + MNL_ATTR_HDRLEN > buflen)
 		return NULL;
 	return mnl_attr_nest_start(nlh, type);
 }
-EXPORT_SYMBOL(mnl_attr_nest_start_check);
 
 /**
  * mnl_attr_nest_end - end an attribute nest
@@ -725,12 +711,11 @@ EXPORT_SYMBOL(mnl_attr_nest_start_check);
  *
  * This function updates the attribute header that identifies the nest.
  */
-void
+EXPORT_SYMBOL void
 mnl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *start)
 {
 	start->nla_len = mnl_nlmsg_get_payload_tail(nlh) - (void *)start;
 }
-EXPORT_SYMBOL(mnl_attr_nest_end);
 
 /**
  * mnl_attr_nest_cancel - cancel an attribute nest
@@ -739,12 +724,11 @@ EXPORT_SYMBOL(mnl_attr_nest_end);
  *
  * This function updates the attribute header that identifies the nest.
  */
-void
+EXPORT_SYMBOL void
 mnl_attr_nest_cancel(struct nlmsghdr *nlh, struct nlattr *start)
 {
 	nlh->nlmsg_len -= mnl_nlmsg_get_payload_tail(nlh) - (void *)start;
 }
-EXPORT_SYMBOL(mnl_attr_nest_cancel);
 
 /**
  * @}
diff --git a/src/callback.c b/src/callback.c
index f023401..c626916 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -126,15 +126,14 @@ out:
  * to EPROTO. If the dump was interrupted, errno is set to EINTR and you should
  * request a new fresh dump again.
  */
-int
+EXPORT_SYMBOL int
 mnl_cb_run2(const void *buf, size_t numbytes, unsigned int seq,
-	    unsigned int portid, mnl_cb_t cb_data, void *data,
-	    mnl_cb_t *cb_ctl_array, unsigned int cb_ctl_array_len)
+            unsigned int portid, mnl_cb_t cb_data, void *data,
+            mnl_cb_t *cb_ctl_array, unsigned int cb_ctl_array_len)
 {
 	return __mnl_cb_run(buf, numbytes, seq, portid, cb_data, data,
 			    cb_ctl_array, cb_ctl_array_len);
 }
-EXPORT_SYMBOL(mnl_cb_run2);
 
 /**
  * mnl_cb_run - callback runqueue for netlink messages (simplified version)
@@ -155,13 +154,12 @@ EXPORT_SYMBOL(mnl_cb_run2);
  *
  * This function propagates the callback return value.
  */
-int
+EXPORT_SYMBOL int
 mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq,
-	   unsigned int portid, mnl_cb_t cb_data, void *data)
+           unsigned int portid, mnl_cb_t cb_data, void *data)
 {
 	return __mnl_cb_run(buf, numbytes, seq, portid, cb_data, data, NULL, 0);
 }
-EXPORT_SYMBOL(mnl_cb_run);
 
 /**
  * @}
diff --git a/src/internal.h b/src/internal.h
index 3a88d1a..47a8314 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -3,8 +3,7 @@
 
 #include "config.h"
 #ifdef HAVE_VISIBILITY_HIDDEN
-#	define __visible	__attribute__((visibility("default")))
-#	define EXPORT_SYMBOL(x)	typeof(x) (x) __visible
+#	define EXPORT_SYMBOL	__attribute__((visibility("default")))
 #else
 #	define EXPORT_SYMBOL
 #endif
diff --git a/src/nlmsg.c b/src/nlmsg.c
index fd2f698..8f3d755 100644
--- a/src/nlmsg.c
+++ b/src/nlmsg.c
@@ -51,11 +51,11 @@
  * This function returns the size of a netlink message (header plus payload)
  * without alignment.
  */
-size_t mnl_nlmsg_size(size_t len)
+EXPORT_SYMBOL size_t
+mnl_nlmsg_size(size_t len)
 {
 	return len + MNL_NLMSG_HDRLEN;
 }
-EXPORT_SYMBOL(mnl_nlmsg_size);
 
 /**
  * mnl_nlmsg_get_payload_len - get the length of the Netlink payload
@@ -64,11 +64,11 @@ EXPORT_SYMBOL(mnl_nlmsg_size);
  * This function returns the Length of the netlink payload, ie. the length
  * of the full message minus the size of the Netlink header.
  */
-size_t mnl_nlmsg_get_payload_len(const struct nlmsghdr *nlh)
+EXPORT_SYMBOL size_t
+mnl_nlmsg_get_payload_len(const struct nlmsghdr *nlh)
 {
 	return nlh->nlmsg_len - MNL_NLMSG_HDRLEN;
 }
-EXPORT_SYMBOL(mnl_nlmsg_get_payload_len);
 
 /**
  * mnl_nlmsg_put_header - reserve and prepare room for Netlink header
@@ -79,7 +79,8 @@ EXPORT_SYMBOL(mnl_nlmsg_get_payload_len);
  * initializes the nlmsg_len field to the size of the Netlink header. This
  * function returns a pointer to the Netlink header structure.
  */
-struct nlmsghdr *mnl_nlmsg_put_header(void *buf)
+EXPORT_SYMBOL struct nlmsghdr *
+mnl_nlmsg_put_header(void *buf)
 {
 	int len = MNL_ALIGN(sizeof(struct nlmsghdr));
 	struct nlmsghdr *nlh = buf;
@@ -88,7 +89,6 @@ struct nlmsghdr *mnl_nlmsg_put_header(void *buf)
 	nlh->nlmsg_len = len;
 	return nlh;
 }
-EXPORT_SYMBOL(mnl_nlmsg_put_header);
 
 /**
  * mnl_nlmsg_put_extra_header - reserve and prepare room for an extra header
@@ -101,7 +101,7 @@ EXPORT_SYMBOL(mnl_nlmsg_put_header);
  * you call this function. This function returns a pointer to the extra
  * header.
  */
-void *
+EXPORT_SYMBOL void *
 mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size)
 {
 	char *ptr = (char *)nlh + nlh->nlmsg_len;
@@ -110,7 +110,6 @@ mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size)
 	memset(ptr, 0, len);
 	return ptr;
 }
-EXPORT_SYMBOL(mnl_nlmsg_put_extra_header);
 
 /**
  * mnl_nlmsg_get_payload - get a pointer to the payload of the netlink message
@@ -118,11 +117,11 @@ EXPORT_SYMBOL(mnl_nlmsg_put_extra_header);
  *
  * This function returns a pointer to the payload of the netlink message.
  */
-void *mnl_nlmsg_get_payload(const struct nlmsghdr *nlh)
+EXPORT_SYMBOL void *
+mnl_nlmsg_get_payload(const struct nlmsghdr *nlh)
 {
 	return (void *)nlh + MNL_NLMSG_HDRLEN;
 }
-EXPORT_SYMBOL(mnl_nlmsg_get_payload);
 
 /**
  * mnl_nlmsg_get_payload_offset - get a pointer to the payload of the message
@@ -132,12 +131,11 @@ EXPORT_SYMBOL(mnl_nlmsg_get_payload);
  * This function returns a pointer to the payload of the netlink message plus
  * a given offset.
  */
-void *
+EXPORT_SYMBOL void *
 mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh, size_t offset)
 {
 	return (void *)nlh + MNL_NLMSG_HDRLEN + MNL_ALIGN(offset);
 }
-EXPORT_SYMBOL(mnl_nlmsg_get_payload_offset);
 
 /**
  * mnl_nlmsg_ok - check a there is room for netlink message
@@ -155,13 +153,13 @@ EXPORT_SYMBOL(mnl_nlmsg_get_payload_offset);
  * The len parameter may become negative in malformed messages during message
  * iteration, that is why we use a signed integer.
  */
-bool mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len)
+EXPORT_SYMBOL bool
+mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len)
 {
 	return len >= (int)sizeof(struct nlmsghdr) &&
 	       nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
 	       (int)nlh->nlmsg_len <= len;
 }
-EXPORT_SYMBOL(mnl_nlmsg_ok);
 
 /**
  * mnl_nlmsg_next - get the next netlink message in a multipart message
@@ -176,13 +174,12 @@ EXPORT_SYMBOL(mnl_nlmsg_ok);
  * You have to use mnl_nlmsg_ok() to check if the next Netlink message is
  * valid.
  */
-struct nlmsghdr *
+EXPORT_SYMBOL struct nlmsghdr *
 mnl_nlmsg_next(const struct nlmsghdr *nlh, int *len)
 {
 	*len -= MNL_ALIGN(nlh->nlmsg_len);
 	return (struct nlmsghdr *)((void *)nlh + MNL_ALIGN(nlh->nlmsg_len));
 }
-EXPORT_SYMBOL(mnl_nlmsg_next);
 
 /**
  * mnl_nlmsg_get_payload_tail - get the ending of the netlink message
@@ -192,11 +189,11 @@ EXPORT_SYMBOL(mnl_nlmsg_next);
  * to build a message since we continue adding attributes at the end of the
  * message.
  */
-void *mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh)
+EXPORT_SYMBOL void *
+mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh)
 {
 	return (void *)nlh + MNL_ALIGN(nlh->nlmsg_len);
 }
-EXPORT_SYMBOL(mnl_nlmsg_get_payload_tail);
 
 /**
  * mnl_nlmsg_seq_ok - perform sequence tracking
@@ -212,12 +209,11 @@ EXPORT_SYMBOL(mnl_nlmsg_get_payload_tail);
  * socket to send commands to kernel-space (that we want to track) and to
  * listen to events (that we do not track).
  */
-bool
+EXPORT_SYMBOL bool
 mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh, unsigned int seq)
 {
 	return nlh->nlmsg_seq && seq ? nlh->nlmsg_seq == seq : true;
 }
-EXPORT_SYMBOL(mnl_nlmsg_seq_ok);
 
 /**
  * mnl_nlmsg_portid_ok - perform portID origin check
@@ -233,12 +229,11 @@ EXPORT_SYMBOL(mnl_nlmsg_seq_ok);
  * to kernel-space (that we want to track) and to listen to events (that we
  * do not track).
  */
-bool
+EXPORT_SYMBOL bool
 mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh, unsigned int portid)
 {
 	return nlh->nlmsg_pid && portid ? nlh->nlmsg_pid == portid : true;
 }
-EXPORT_SYMBOL(mnl_nlmsg_portid_ok);
 
 static void mnl_nlmsg_fprintf_header(FILE *fd, const struct nlmsghdr *nlh)
 {
@@ -369,9 +364,9 @@ mnl_nlmsg_fprintf_payload(FILE *fd, const struct nlmsghdr *nlh,
  * - N, that indicates that NLA_F_NESTED is set.
  * - B, that indicates that NLA_F_NET_BYTEORDER is set.
  */
-void
+EXPORT_SYMBOL void
 mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen,
-		  size_t extra_header_size)
+                  size_t extra_header_size)
 {
 	const struct nlmsghdr *nlh = data;
 	int len = datalen;
@@ -382,7 +377,6 @@ mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen,
 		nlh = mnl_nlmsg_next(nlh, &len);
 	}
 }
-EXPORT_SYMBOL(mnl_nlmsg_fprintf);
 
 /**
  * \defgroup batch Netlink message batch helpers
@@ -440,7 +434,8 @@ struct mnl_nlmsg_batch {
  * the heap, no restrictions in this regard. This function returns NULL on
  * error.
  */
-struct mnl_nlmsg_batch *mnl_nlmsg_batch_start(void *buf, size_t limit)
+EXPORT_SYMBOL struct mnl_nlmsg_batch *
+mnl_nlmsg_batch_start(void *buf, size_t limit)
 {
 	struct mnl_nlmsg_batch *b;
 
@@ -456,7 +451,6 @@ struct mnl_nlmsg_batch *mnl_nlmsg_batch_start(void *buf, size_t limit)
 
 	return b;
 }
-EXPORT_SYMBOL(mnl_nlmsg_batch_start);
 
 /**
  * mnl_nlmsg_batch_stop - release a batch
@@ -464,11 +458,11 @@ EXPORT_SYMBOL(mnl_nlmsg_batch_start);
  *
  * This function releases the batch allocated by mnl_nlmsg_batch_start().
  */
-void mnl_nlmsg_batch_stop(struct mnl_nlmsg_batch *b)
+EXPORT_SYMBOL void
+mnl_nlmsg_batch_stop(struct mnl_nlmsg_batch *b)
 {
 	free(b);
 }
-EXPORT_SYMBOL(mnl_nlmsg_batch_stop);
 
 /**
  * mnl_nlmsg_batch_next - get room for the next message in the batch
@@ -481,7 +475,8 @@ EXPORT_SYMBOL(mnl_nlmsg_batch_stop);
  * You have to put at least one message in the batch before calling this
  * function, otherwise your application is likely to crash.
  */
-bool mnl_nlmsg_batch_next(struct mnl_nlmsg_batch *b)
+EXPORT_SYMBOL bool
+mnl_nlmsg_batch_next(struct mnl_nlmsg_batch *b)
 {
 	struct nlmsghdr *nlh = b->cur;
 
@@ -493,7 +488,6 @@ bool mnl_nlmsg_batch_next(struct mnl_nlmsg_batch *b)
 	b->buflen += nlh->nlmsg_len;
 	return true;
 }
-EXPORT_SYMBOL(mnl_nlmsg_batch_next);
 
 /**
  * mnl_nlmsg_batch_reset - reset the batch
@@ -503,7 +497,8 @@ EXPORT_SYMBOL(mnl_nlmsg_batch_next);
  * new one. This function moves the last message which does not fit the
  * batch to the head of the buffer, if any.
  */
-void mnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b)
+EXPORT_SYMBOL void
+mnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b)
 {
 	if (b->overflow) {
 		struct nlmsghdr *nlh = b->cur;
@@ -516,7 +511,6 @@ void mnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b)
 		b->cur = b->buf;
 	}
 }
-EXPORT_SYMBOL(mnl_nlmsg_batch_reset);
 
 /**
  * mnl_nlmsg_batch_size - get current size of the batch
@@ -524,11 +518,11 @@ EXPORT_SYMBOL(mnl_nlmsg_batch_reset);
  *
  * This function returns the current size of the batch.
  */
-size_t mnl_nlmsg_batch_size(struct mnl_nlmsg_batch *b)
+EXPORT_SYMBOL size_t
+mnl_nlmsg_batch_size(struct mnl_nlmsg_batch *b)
 {
 	return b->buflen;
 }
-EXPORT_SYMBOL(mnl_nlmsg_batch_size);
 
 /**
  * mnl_nlmsg_batch_head - get head of this batch
@@ -537,11 +531,11 @@ EXPORT_SYMBOL(mnl_nlmsg_batch_size);
  * This function returns a pointer to the head of the batch, which is the
  * beginning of the buffer that is used.
  */
-void *mnl_nlmsg_batch_head(struct mnl_nlmsg_batch *b)
+EXPORT_SYMBOL void *
+mnl_nlmsg_batch_head(struct mnl_nlmsg_batch *b)
 {
 	return b->buf;
 }
-EXPORT_SYMBOL(mnl_nlmsg_batch_head);
 
 /**
  * mnl_nlmsg_batch_current - returns current position in the batch
@@ -550,11 +544,11 @@ EXPORT_SYMBOL(mnl_nlmsg_batch_head);
  * This function returns a pointer to the current position in the buffer
  * that is used to store the batch.
  */
-void *mnl_nlmsg_batch_current(struct mnl_nlmsg_batch *b)
+EXPORT_SYMBOL void *
+mnl_nlmsg_batch_current(struct mnl_nlmsg_batch *b)
 {
 	return b->cur;
 }
-EXPORT_SYMBOL(mnl_nlmsg_batch_current);
 
 /**
  * mnl_nlmsg_batch_is_empty - check if there is any message in the batch
@@ -562,11 +556,11 @@ EXPORT_SYMBOL(mnl_nlmsg_batch_current);
  *
  * This function returns true if the batch is empty.
  */
-bool mnl_nlmsg_batch_is_empty(struct mnl_nlmsg_batch *b)
+EXPORT_SYMBOL bool
+mnl_nlmsg_batch_is_empty(struct mnl_nlmsg_batch *b)
 {
 	return b->buflen == 0;
 }
-EXPORT_SYMBOL(mnl_nlmsg_batch_is_empty);
 
 /**
  * @}
diff --git a/src/socket.c b/src/socket.c
index 86657d4..bd8763e 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -82,11 +82,11 @@ struct mnl_socket {
  *
  * This function returns the file descriptor of a given netlink socket.
  */
-int mnl_socket_get_fd(const struct mnl_socket *nl)
+EXPORT_SYMBOL int
+mnl_socket_get_fd(const struct mnl_socket *nl)
 {
 	return nl->fd;
 }
-EXPORT_SYMBOL(mnl_socket_get_fd);
 
 /**
  * mnl_socket_get_portid - obtain Netlink PortID from netlink socket
@@ -97,11 +97,11 @@ EXPORT_SYMBOL(mnl_socket_get_fd);
  * which is not always true. This is the case if you open more than one
  * socket that is binded to the same Netlink subsystem from the same process.
  */
-unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
+EXPORT_SYMBOL unsigned int
+mnl_socket_get_portid(const struct mnl_socket *nl)
 {
 	return nl->addr.nl_pid;
 }
-EXPORT_SYMBOL(mnl_socket_get_portid);
 
 /**
  * mnl_socket_open - open a netlink socket
@@ -110,7 +110,8 @@ EXPORT_SYMBOL(mnl_socket_get_portid);
  * On error, it returns NULL and errno is appropriately set. Otherwise, it
  * returns a valid pointer to the mnl_socket structure.
  */
-struct mnl_socket *mnl_socket_open(int bus)
+EXPORT_SYMBOL struct mnl_socket *
+mnl_socket_open(int bus)
 {
 	struct mnl_socket *nl;
 
@@ -126,7 +127,6 @@ struct mnl_socket *mnl_socket_open(int bus)
 
 	return nl;
 }
-EXPORT_SYMBOL(mnl_socket_open);
 
 /**
  * mnl_socket_fdopen - associates a mnl_socket object with pre-existing socket.
@@ -139,7 +139,8 @@ EXPORT_SYMBOL(mnl_socket_open);
  * Note that mnl_socket_get_portid() returns 0 if this function is used with
  * non-netlink socket.
  */
-struct mnl_socket *mnl_socket_fdopen(int fd)
+EXPORT_SYMBOL struct mnl_socket *
+mnl_socket_fdopen(int fd)
 {
 	int ret;
 	struct mnl_socket *nl;
@@ -160,7 +161,6 @@ struct mnl_socket *mnl_socket_fdopen(int fd)
 
 	return nl;
 }
-EXPORT_SYMBOL(mnl_socket_fdopen);
 
 /**
  * mnl_socket_bind - bind netlink socket
@@ -172,7 +172,8 @@ EXPORT_SYMBOL(mnl_socket_fdopen);
  * success, 0 is returned. You can use MNL_SOCKET_AUTOPID which is 0 for
  * automatic port ID selection.
  */
-int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
+EXPORT_SYMBOL int
+mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
 {
 	int ret;
 	socklen_t addr_len;
@@ -200,7 +201,6 @@ int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
 	}
 	return 0;
 }
-EXPORT_SYMBOL(mnl_socket_bind);
 
 /**
  * mnl_socket_sendto - send a netlink message of a certain size
@@ -211,7 +211,7 @@ EXPORT_SYMBOL(mnl_socket_bind);
  * On error, it returns -1 and errno is appropriately set. Otherwise, it 
  * returns the number of bytes sent.
  */
-ssize_t
+EXPORT_SYMBOL ssize_t
 mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len)
 {
 	static const struct sockaddr_nl snl = {
@@ -220,7 +220,6 @@ mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len)
 	return sendto(nl->fd, buf, len, 0, 
 		      (struct sockaddr *) &snl, sizeof(snl));
 }
-EXPORT_SYMBOL(mnl_socket_sendto);
 
 /**
  * mnl_socket_recvfrom - receive a netlink message
@@ -236,7 +235,7 @@ EXPORT_SYMBOL(mnl_socket_sendto);
  * buffer size ensures that your buffer is big enough to store the netlink
  * message without truncating it.
  */
-ssize_t
+EXPORT_SYMBOL ssize_t
 mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
 {
 	ssize_t ret;
@@ -268,7 +267,6 @@ mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
 	}
 	return ret;
 }
-EXPORT_SYMBOL(mnl_socket_recvfrom);
 
 /**
  * mnl_socket_close - close a given netlink socket
@@ -277,13 +275,13 @@ EXPORT_SYMBOL(mnl_socket_recvfrom);
  * On error, this function returns -1 and errno is appropriately set.
  * On success, it returns 0.
  */
-int mnl_socket_close(struct mnl_socket *nl)
+EXPORT_SYMBOL int
+mnl_socket_close(struct mnl_socket *nl)
 {
 	int ret = close(nl->fd);
 	free(nl);
 	return ret;
 }
-EXPORT_SYMBOL(mnl_socket_close);
 
 /**
  * mnl_socket_setsockopt - set Netlink socket option
@@ -310,12 +308,12 @@ EXPORT_SYMBOL(mnl_socket_close);
  *
  * On error, this function returns -1 and errno is appropriately set.
  */
-int mnl_socket_setsockopt(const struct mnl_socket *nl, int type,
-			  void *buf, socklen_t len)
+EXPORT_SYMBOL int
+mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf,
+                      socklen_t len)
 {
 	return setsockopt(nl->fd, SOL_NETLINK, type, buf, len);
 }
-EXPORT_SYMBOL(mnl_socket_setsockopt);
 
 /**
  * mnl_socket_getsockopt - get a Netlink socket option
@@ -326,12 +324,12 @@ EXPORT_SYMBOL(mnl_socket_setsockopt);
  *
  * On error, this function returns -1 and errno is appropriately set.
  */
-int mnl_socket_getsockopt(const struct mnl_socket *nl, int type,
-			  void *buf, socklen_t *len)
+EXPORT_SYMBOL int
+mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf,
+                      socklen_t *len)
 {
 	return getsockopt(nl->fd, SOL_NETLINK, type, buf, len);
 }
-EXPORT_SYMBOL(mnl_socket_getsockopt);
 
 /**
  * @}
-- 
2.5.3


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] libmnl: Failed to build with clang, incompatible EXPORT_SYMBOL(x) macro
  2015-09-25  4:07 [PATCH] libmnl: Failed to build with clang, incompatible EXPORT_SYMBOL(x) macro Neutron Soutmun
@ 2015-09-30 22:12 ` Pablo Neira Ayuso
  2015-10-01  3:15   ` Neutron Soutmun
  2015-10-01  9:20   ` Jan Engelhardt
  0 siblings, 2 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2015-09-30 22:12 UTC (permalink / raw)
  To: Neutron Soutmun; +Cc: netfilter-devel

On Fri, Sep 25, 2015 at 11:07:45AM +0700, Neutron Soutmun wrote:
> The EXPORT_SYMBOL(x) macro causes clang compile error and warning
> messges:
>   error,   "note: previous definition is here"
>   warning, "warning: attribute declaration must precede definition
>             [-Wignored-attributes]"
>   See: [1]
> 
> This proposed patch has been prepared to fix this error which make the
> EXPORT_SYMBOL macro define a precede definition of an attribute
> declaration. This approach is both compatible with gcc and clang.

We have more libraries using this approach, which resembles kernel
coding. So we would need to update them all, which is a bit annoying.

Though this warning results in a real problem since symbols will not
be exported.

Why is clang rejecting this?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libmnl: Failed to build with clang, incompatible EXPORT_SYMBOL(x) macro
  2015-09-30 22:12 ` Pablo Neira Ayuso
@ 2015-10-01  3:15   ` Neutron Soutmun
  2015-10-01  9:20   ` Jan Engelhardt
  1 sibling, 0 replies; 8+ messages in thread
From: Neutron Soutmun @ 2015-10-01  3:15 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

On Thu, Oct 1, 2015 at 5:12 AM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> We have more libraries using this approach, which resembles kernel
> coding. So we would need to update them all, which is a bit annoying.

Ah, I see. I try to find many approaches to easy fix this but not success.

Refer to [1] which the reporter proposes the patch

== 8< ==

ifeq ($(shell $(CC) --version | grep -c "clang version"),1)
CFLAGS += -fvisibility=default
endif

== 8< ==

I have tested, the symbols exported but I think It will override the
visibility attributes, therefore, I have prepared my proposed patch.

> Though this warning results in a real problem since symbols will not
> be exported.
> Why is clang rejecting this?

I'm not sure. It seems that clang expands the EXPORT_SYMBOL() as
a redefined of it's exported symbol function which is far different from gcc
implementation.

I try to seek more info [2] and see the export.h source [3] but
I have no idea for what's next -_-''

Best regards,
Neutron Soutmun

[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=789480
[2] http://llvm.linuxfoundation.org/index.php/Main_Page
[3] http://lxr.free-electrons.com/source/include/linux/export.h

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libmnl: Failed to build with clang, incompatible EXPORT_SYMBOL(x) macro
  2015-09-30 22:12 ` Pablo Neira Ayuso
  2015-10-01  3:15   ` Neutron Soutmun
@ 2015-10-01  9:20   ` Jan Engelhardt
  2015-10-01  9:30     ` Neutron Soutmun
  1 sibling, 1 reply; 8+ messages in thread
From: Jan Engelhardt @ 2015-10-01  9:20 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Neutron Soutmun, netfilter-devel


On Thursday 2015-10-01 00:12, Pablo Neira Ayuso wrote:
>On Fri, Sep 25, 2015 at 11:07:45AM +0700, Neutron Soutmun wrote:
>> The EXPORT_SYMBOL(x) macro causes clang compile error and warning
>> messges:
>>   error,   "note: previous definition is here"
>>   warning, "warning: attribute declaration must precede definition
>>             [-Wignored-attributes]"
>>   See: [1]
>> 
>> This proposed patch has been prepared to fix this error which make the
>> EXPORT_SYMBOL macro define a precede definition of an attribute
>> declaration. This approach is both compatible with gcc and clang.
>
>We have more libraries using this approach, which resembles kernel
>coding. So we would need to update them all, which is a bit annoying.

If you use an export map (-Wl,--version-script=), you don't strictly
need to have any of the EXPORT_SYMBOL tags in the C source.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libmnl: Failed to build with clang, incompatible EXPORT_SYMBOL(x) macro
  2015-10-01  9:20   ` Jan Engelhardt
@ 2015-10-01  9:30     ` Neutron Soutmun
  2015-10-01 10:15       ` Pablo Neira Ayuso
  0 siblings, 1 reply; 8+ messages in thread
From: Neutron Soutmun @ 2015-10-01  9:30 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Pablo Neira Ayuso, netfilter-devel

On Thu, Oct 1, 2015 at 4:20 PM, Jan Engelhardt <jengelh@inai.de> wrote:
>
> On Thursday 2015-10-01 00:12, Pablo Neira Ayuso wrote:
>>On Fri, Sep 25, 2015 at 11:07:45AM +0700, Neutron Soutmun wrote:
>>> The EXPORT_SYMBOL(x) macro causes clang compile error and warning
>>> messges:
>>>   error,   "note: previous definition is here"
>>>   warning, "warning: attribute declaration must precede definition
>>>             [-Wignored-attributes]"
>>>   See: [1]
>>>
>>> This proposed patch has been prepared to fix this error which make the
>>> EXPORT_SYMBOL macro define a precede definition of an attribute
>>> declaration. This approach is both compatible with gcc and clang.
>>
>>We have more libraries using this approach, which resembles kernel
>>coding. So we would need to update them all, which is a bit annoying.
>
> If you use an export map (-Wl,--version-script=), you don't strictly
> need to have any of the EXPORT_SYMBOL tags in the C source.

+1

Cheers,
Neutron Soutmun

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libmnl: Failed to build with clang, incompatible EXPORT_SYMBOL(x) macro
  2015-10-01  9:30     ` Neutron Soutmun
@ 2015-10-01 10:15       ` Pablo Neira Ayuso
  2015-10-01 10:29         ` Neutron Soutmun
  0 siblings, 1 reply; 8+ messages in thread
From: Pablo Neira Ayuso @ 2015-10-01 10:15 UTC (permalink / raw)
  To: Neutron Soutmun; +Cc: Jan Engelhardt, netfilter-devel

On Thu, Oct 01, 2015 at 04:30:23PM +0700, Neutron Soutmun wrote:
> On Thu, Oct 1, 2015 at 4:20 PM, Jan Engelhardt <jengelh@inai.de> wrote:
> >
> > On Thursday 2015-10-01 00:12, Pablo Neira Ayuso wrote:
> >>On Fri, Sep 25, 2015 at 11:07:45AM +0700, Neutron Soutmun wrote:
> >>> The EXPORT_SYMBOL(x) macro causes clang compile error and warning
> >>> messges:
> >>>   error,   "note: previous definition is here"
> >>>   warning, "warning: attribute declaration must precede definition
> >>>             [-Wignored-attributes]"
> >>>   See: [1]
> >>>
> >>> This proposed patch has been prepared to fix this error which make the
> >>> EXPORT_SYMBOL macro define a precede definition of an attribute
> >>> declaration. This approach is both compatible with gcc and clang.
> >>
> >>We have more libraries using this approach, which resembles kernel
> >>coding. So we would need to update them all, which is a bit annoying.
> >
> > If you use an export map (-Wl,--version-script=), you don't strictly
> > need to have any of the EXPORT_SYMBOL tags in the C source.
> 
> +1

That sounds as a smaller patch, please send it to me for the existing
libraries that we have. Thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libmnl: Failed to build with clang, incompatible EXPORT_SYMBOL(x) macro
  2015-10-01 10:15       ` Pablo Neira Ayuso
@ 2015-10-01 10:29         ` Neutron Soutmun
  2015-10-01 11:12           ` Neutron Soutmun
  0 siblings, 1 reply; 8+ messages in thread
From: Neutron Soutmun @ 2015-10-01 10:29 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Jan Engelhardt, netfilter-devel

On Thu, Oct 1, 2015 at 5:15 PM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Thu, Oct 01, 2015 at 04:30:23PM +0700, Neutron Soutmun wrote:
>> On Thu, Oct 1, 2015 at 4:20 PM, Jan Engelhardt <jengelh@inai.de> wrote:
>> >
>> > On Thursday 2015-10-01 00:12, Pablo Neira Ayuso wrote:
>> >>On Fri, Sep 25, 2015 at 11:07:45AM +0700, Neutron Soutmun wrote:
>> >>> The EXPORT_SYMBOL(x) macro causes clang compile error and warning
>> >>> messges:
>> >>>   error,   "note: previous definition is here"
>> >>>   warning, "warning: attribute declaration must precede definition
>> >>>             [-Wignored-attributes]"
>> >>>   See: [1]
>> >>>
>> >>> This proposed patch has been prepared to fix this error which make the
>> >>> EXPORT_SYMBOL macro define a precede definition of an attribute
>> >>> declaration. This approach is both compatible with gcc and clang.
>> >>
>> >>We have more libraries using this approach, which resembles kernel
>> >>coding. So we would need to update them all, which is a bit annoying.
>> >
>> > If you use an export map (-Wl,--version-script=), you don't strictly
>> > need to have any of the EXPORT_SYMBOL tags in the C source.
>>
>> +1
>
> That sounds as a smaller patch, please send it to me for the existing
> libraries that we have. Thanks.

I have tested with libipset, clang exports the symbols fine and no any warnings.

libmnl has implemented the export map already,
therefore, I'll prepare and test the patch that drop all EXPORT_SYMBOL tags.

Best regards,
Neutron Soutmun

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] libmnl: Failed to build with clang, incompatible EXPORT_SYMBOL(x) macro
  2015-10-01 10:29         ` Neutron Soutmun
@ 2015-10-01 11:12           ` Neutron Soutmun
  0 siblings, 0 replies; 8+ messages in thread
From: Neutron Soutmun @ 2015-10-01 11:12 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Jan Engelhardt, netfilter-devel

I have prepared the patch that drop all EXPORT_SYMBOL tags
Please find [1] - [PATCH] libmnl: Drop the EXPORT_SYMBOL() tags


Best regards,
Neutron Soutmun

[1] https://marc.info/?l=netfilter-devel&m=144369760923041&w=2

On Thu, Oct 1, 2015 at 5:29 PM, Neutron Soutmun <neo.neutron@gmail.com> wrote:
> On Thu, Oct 1, 2015 at 5:15 PM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
>> On Thu, Oct 01, 2015 at 04:30:23PM +0700, Neutron Soutmun wrote:
>>> On Thu, Oct 1, 2015 at 4:20 PM, Jan Engelhardt <jengelh@inai.de> wrote:
>>> >
>>> > On Thursday 2015-10-01 00:12, Pablo Neira Ayuso wrote:
>>> >>On Fri, Sep 25, 2015 at 11:07:45AM +0700, Neutron Soutmun wrote:
>>> >>> The EXPORT_SYMBOL(x) macro causes clang compile error and warning
>>> >>> messges:
>>> >>>   error,   "note: previous definition is here"
>>> >>>   warning, "warning: attribute declaration must precede definition
>>> >>>             [-Wignored-attributes]"
>>> >>>   See: [1]
>>> >>>
>>> >>> This proposed patch has been prepared to fix this error which make the
>>> >>> EXPORT_SYMBOL macro define a precede definition of an attribute
>>> >>> declaration. This approach is both compatible with gcc and clang.
>>> >>
>>> >>We have more libraries using this approach, which resembles kernel
>>> >>coding. So we would need to update them all, which is a bit annoying.
>>> >
>>> > If you use an export map (-Wl,--version-script=), you don't strictly
>>> > need to have any of the EXPORT_SYMBOL tags in the C source.
>>>
>>> +1
>>
>> That sounds as a smaller patch, please send it to me for the existing
>> libraries that we have. Thanks.
>
> I have tested with libipset, clang exports the symbols fine and no any warnings.
>
> libmnl has implemented the export map already,
> therefore, I'll prepare and test the patch that drop all EXPORT_SYMBOL tags.
>
> Best regards,
> Neutron Soutmun

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-10-01 11:12 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-25  4:07 [PATCH] libmnl: Failed to build with clang, incompatible EXPORT_SYMBOL(x) macro Neutron Soutmun
2015-09-30 22:12 ` Pablo Neira Ayuso
2015-10-01  3:15   ` Neutron Soutmun
2015-10-01  9:20   ` Jan Engelhardt
2015-10-01  9:30     ` Neutron Soutmun
2015-10-01 10:15       ` Pablo Neira Ayuso
2015-10-01 10:29         ` Neutron Soutmun
2015-10-01 11:12           ` Neutron Soutmun

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).