summaryrefslogtreecommitdiff
path: root/libattr/syscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'libattr/syscalls.c')
-rw-r--r--libattr/syscalls.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/libattr/syscalls.c b/libattr/syscalls.c
index 721ad7f..907560a 100644
--- a/libattr/syscalls.c
+++ b/libattr/syscalls.c
@@ -26,6 +26,27 @@
#include <sys/syscall.h>
#include <sys/xattr.h>
+/*
+ * Versioning of compat symbols:
+ * prefer symver attribute if available (since gcc 10),
+ * fall back to traditional .symver asm directive otherwise.
+ */
+#ifdef __has_attribute
+# if __has_attribute(__symver__)
+# define SYMVER(cn, vn) __typeof(cn) cn __attribute__((__symver__(vn)))
+# elif __has_attribute(__no_reorder__)
+ /*
+ * Avoid wrong partitioning with older gcc and LTO. May not work reliably
+ * with all versions; use -flto-partition=none if you encounter problems.
+ */
+# define SYMVER(cn, vn) __typeof(cn) cn __attribute__((__no_reorder__)); \
+ __asm__(".symver " #cn "," vn)
+# endif
+#endif
+#ifndef SYMVER
+# define SYMVER(cn, vn) __asm__(".symver " #cn "," vn)
+#endif
+
#ifdef HAVE_VISIBILITY_ATTRIBUTE
# pragma GCC visibility push(default)
#endif
@@ -35,66 +56,78 @@ int libattr_setxattr(const char *path, const char *name,
{
return syscall(__NR_setxattr, path, name, value, size, flags);
}
+SYMVER(libattr_setxattr, "setxattr@ATTR_1.0");
int libattr_lsetxattr(const char *path, const char *name,
void *value, size_t size, int flags)
{
return syscall(__NR_lsetxattr, path, name, value, size, flags);
}
+SYMVER(libattr_lsetxattr, "lsetxattr@ATTR_1.0");
int libattr_fsetxattr(int filedes, const char *name,
void *value, size_t size, int flags)
{
return syscall(__NR_fsetxattr, filedes, name, value, size, flags);
}
+SYMVER(libattr_fsetxattr, "fsetxattr@ATTR_1.0");
ssize_t libattr_getxattr(const char *path, const char *name,
void *value, size_t size)
{
return syscall(__NR_getxattr, path, name, value, size);
}
+SYMVER(libattr_getxattr, "getxattr@ATTR_1.0");
ssize_t libattr_lgetxattr(const char *path, const char *name,
void *value, size_t size)
{
return syscall(__NR_lgetxattr, path, name, value, size);
}
+SYMVER(libattr_lgetxattr, "lgetxattr@ATTR_1.0");
ssize_t libattr_fgetxattr(int filedes, const char *name,
void *value, size_t size)
{
return syscall(__NR_fgetxattr, filedes, name, value, size);
}
+SYMVER(libattr_fgetxattr, "fgetxattr@ATTR_1.0");
ssize_t libattr_listxattr(const char *path, char *list, size_t size)
{
return syscall(__NR_listxattr, path, list, size);
}
+SYMVER(libattr_listxattr, "listxattr@ATTR_1.0");
ssize_t libattr_llistxattr(const char *path, char *list, size_t size)
{
return syscall(__NR_llistxattr, path, list, size);
}
+SYMVER(libattr_llistxattr, "llistxattr@ATTR_1.0");
ssize_t libattr_flistxattr(int filedes, char *list, size_t size)
{
return syscall(__NR_flistxattr, filedes, list, size);
}
+SYMVER(libattr_flistxattr, "flistxattr@ATTR_1.0");
int libattr_removexattr(const char *path, const char *name)
{
return syscall(__NR_removexattr, path, name);
}
+SYMVER(libattr_removexattr, "removexattr@ATTR_1.0");
int libattr_lremovexattr(const char *path, const char *name)
{
return syscall(__NR_lremovexattr, path, name);
}
+SYMVER(libattr_lremovexattr, "lremovexattr@ATTR_1.0");
int libattr_fremovexattr(int filedes, const char *name)
{
return syscall(__NR_fremovexattr, filedes, name);
}
+SYMVER(libattr_fremovexattr, "fremovexattr@ATTR_1.0");
#ifdef HAVE_VISIBILITY_ATTRIBUTE
# pragma GCC visibility pop