]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Revert "Prevent more compiler optimization of mockable functions"
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 12 Jul 2017 10:07:17 +0000 (11:07 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 13 Jul 2017 12:07:06 +0000 (13:07 +0100)
This reverts commit e4b980c853d2114b25fa805a84ea288384416221.

When a binary links against a .a archive (as opposed to a shared library),
any symbols which are marked as 'weak' get silently dropped. As a result
when the binary later runs, those 'weak' functions have an address of
0x0 and thus crash when run.

This happened with virtlogd and virtlockd because they don't link to
libvirt.so, but instead just libvirt_util.a and libvirt_rpc.a. The
virRandomBits symbols was weak and so left out of the virtlogd &
virtlockd binaries, despite being required by virHashTable functions.

Various other binaries like libvirt_lxc, libvirt_iohelper, etc also
link directly to .a files instead of libvirt.so, so are potentially
at risk of dropping symbols leading to a later runtime crash.

This is normal linker behaviour because a weak symbol is not treated
as undefined, so nothing forces it to be pulled in from the .a You
have to force the linker to pull in weak symbols using -u$SYMNAME
which is not a practical approach.

This risk is silent bad linkage that affects runtime behaviour is
not acceptable for a fix that was merely trying to fix the test
suite. So stop using __weak__ again.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
21 files changed:
build-aux/mock-noinline.pl
src/check-symfile.pl
src/internal.h
src/qemu/qemu_capspriv.h
src/rpc/virnetsocket.h
src/util/vircommand.h
src/util/vircrypto.h
src/util/virfile.h
src/util/virhostcpu.h
src/util/virmacaddr.h
src/util/virnetdev.h
src/util/virnetdevip.h
src/util/virnetdevopenvswitch.h
src/util/virnetdevtap.h
src/util/virnuma.h
src/util/virrandom.h
src/util/virscsi.h
src/util/virscsivhost.h
src/util/virtpm.h
src/util/virutil.h
src/util/viruuid.h

index 2745d4baf7eb7eaeb8370da2ebeed18d8399c827..eafe20d2e2e8ac0254f264ba1fc29af536aa81fa 100644 (file)
@@ -43,7 +43,7 @@ sub scan_annotations {
         } elsif (/^\s*$/) {
             $func = undef;
         }
-        if (/ATTRIBUTE_MOCKABLE/) {
+        if (/ATTRIBUTE_NOINLINE/) {
             if (defined $func) {
                 $noninlined{$func} = 1;
             }
index 3b062d0a4865ace25f966bc675f33817f7e5d9ae..d59a213eba08dde6e12e07357b7219835b2b392b 100755 (executable)
@@ -52,7 +52,7 @@ foreach my $elflib (@elflibs) {
     open NM, "-|", "nm", $elflib or die "cannot run 'nm $elflib': $!";
 
     while (<NM>) {
-        next unless /^\S+\s(?:[TBDW])\s(\S+)\s*$/;
+        next unless /^\S+\s(?:[TBD])\s(\S+)\s*$/;
 
         $gotsyms{$1} = 1;
     }
index 00edd4fdeb1f399908cf521b463d2ae6561fc833..c29f20f0221e7eb3a011fc3d5f73dc339f6f4374 100644 (file)
 # endif
 
 /**
- * ATTRIBUTE_MOCKABLE:
- *
- * Ensure that the symbol can be overridden in a mock
- * library preload. This implies a number of attributes
- *
- *  - noinline: prevents the body being inlined to
- *              callers,
- *  - noclone: prevents specialized copies of the
- *             function body being created for different
- *             callers
- *  - weak: prevents the compiler making optimizations
- *          such as constant return value propagation
+ * ATTRIBUTE_NOINLINE:
  *
+ * Force compiler not to inline a method. Should be used if
+ * the method need to be overridable by test mocks.
  */
-# ifndef ATTRIBUTE_MOCKABLE
-#  if __GNUC_PREREQ(4, 5)
-#   define ATTRIBUTE_MOCKABLE __attribute__((__noinline__, __noclone__, __weak__))
-#  else
-#   define ATTRIBUTE_MOCKABLE __attribute__((__noinline__, __weak__))
-#  endif
+# ifndef ATTRIBUTE_NOINLINE
+#  define ATTRIBUTE_NOINLINE __attribute__((__noinline__))
 # endif
 
 /**
index 6cc189e4034f1a4b329572220ea872083d59f6ad..94fa75b96016d1f8ffa2f739b7ab1e91e7591f2f 100644 (file)
@@ -95,7 +95,7 @@ virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
 virCPUDefPtr
 virQEMUCapsProbeHostCPUForEmulator(virCapsPtr caps,
                                    virQEMUCapsPtr qemuCaps,
-                                   virDomainVirtType type) ATTRIBUTE_MOCKABLE;
+                                   virDomainVirtType type) ATTRIBUTE_NOINLINE;
 
 void
 virQEMUCapsSetGICCapabilities(virQEMUCapsPtr qemuCaps,
index 3c2945e4b12c254d791b0e083813aa560142dccd..de795af9170bda49f195b103b3fa5b2620370e49 100644 (file)
@@ -137,10 +137,10 @@ int virNetSocketGetUNIXIdentity(virNetSocketPtr sock,
                                 gid_t *gid,
                                 pid_t *pid,
                                 unsigned long long *timestamp)
-    ATTRIBUTE_MOCKABLE;
+    ATTRIBUTE_NOINLINE;
 int virNetSocketGetSELinuxContext(virNetSocketPtr sock,
                                   char **context)
-    ATTRIBUTE_MOCKABLE;
+    ATTRIBUTE_NOINLINE;
 
 int virNetSocketSetBlocking(virNetSocketPtr sock,
                             bool blocking);
index c042a532a4835ea9738e20df33e18ad6d853b631..e7c2e513bae15651fc29f317049be4686e4063b8 100644 (file)
@@ -58,7 +58,7 @@ enum {
 
 void virCommandPassFD(virCommandPtr cmd,
                       int fd,
-                      unsigned int flags) ATTRIBUTE_MOCKABLE;
+                      unsigned int flags) ATTRIBUTE_NOINLINE;
 
 void virCommandPassListenFDs(virCommandPtr cmd);
 
index 50400c6a1895592515ca69fd21a881feb5b0c9e8..068602f5dfc435b48dcb43c5eabc070c27c15536 100644 (file)
@@ -55,6 +55,6 @@ int virCryptoEncryptData(virCryptoCipher algorithm,
     ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(6)
     ATTRIBUTE_NONNULL(8) ATTRIBUTE_NONNULL(9) ATTRIBUTE_RETURN_CHECK;
 
-uint8_t *virCryptoGenerateRandom(size_t nbytes) ATTRIBUTE_MOCKABLE;
+uint8_t *virCryptoGenerateRandom(size_t nbytes) ATTRIBUTE_NOINLINE;
 
 #endif /* __VIR_CRYPTO_H__ */
index 32c9115f57d30c7362ee0d90f94301ffed41db8b..57ceb807210c01358c7f057a3e37117c200db355 100644 (file)
@@ -188,7 +188,7 @@ void virFileActivateDirOverride(const char *argv0)
 
 off_t virFileLength(const char *path, int fd) ATTRIBUTE_NONNULL(1);
 bool virFileIsDir (const char *file) ATTRIBUTE_NONNULL(1);
-bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1) ATTRIBUTE_MOCKABLE;
+bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NOINLINE;
 bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1);
 
 enum {
index 3b30a0d16cd2b24b2f58f0b071764851d78a9fb1..67033de8422bbc7b3ec69ad7891a00e0d1a6c2c0 100644 (file)
@@ -38,7 +38,7 @@ bool virHostCPUHasBitmap(void);
 virBitmapPtr virHostCPUGetPresentBitmap(void);
 virBitmapPtr virHostCPUGetOnlineBitmap(void);
 int virHostCPUGetCount(void);
-int virHostCPUGetThreadsPerSubcore(virArch arch) ATTRIBUTE_MOCKABLE;
+int virHostCPUGetThreadsPerSubcore(virArch arch) ATTRIBUTE_NOINLINE;
 
 int virHostCPUGetMap(unsigned char **cpumap,
                      unsigned int *online,
@@ -51,7 +51,7 @@ int virHostCPUGetInfo(virArch hostarch,
                       unsigned int *cores,
                       unsigned int *threads);
 
-int virHostCPUGetKVMMaxVCPUs(void) ATTRIBUTE_MOCKABLE;
+int virHostCPUGetKVMMaxVCPUs(void) ATTRIBUTE_NOINLINE;
 
 int virHostCPUStatsAssign(virNodeCPUStatsPtr param,
                           const char *name,
index 79492cdf3f150eade8874e93db86a91a6818ae37..f4f5e2ce117288f7b5ee5f72be92dc646e786214 100644 (file)
@@ -48,7 +48,7 @@ void virMacAddrGetRaw(const virMacAddr *src, unsigned char dst[VIR_MAC_BUFLEN]);
 const char *virMacAddrFormat(const virMacAddr *addr,
                              char *str);
 void virMacAddrGenerate(const unsigned char prefix[VIR_MAC_PREFIX_BUFLEN],
-                        virMacAddrPtr addr) ATTRIBUTE_MOCKABLE;
+                        virMacAddrPtr addr) ATTRIBUTE_NOINLINE;
 int virMacAddrParse(const char* str,
                     virMacAddrPtr addr) ATTRIBUTE_RETURN_CHECK;
 int virMacAddrParseHex(const char* str,
index 2e9a9c4057ad1a1aa6c7d13e4f0f845342298219..51fcae544e89421fffccc1e34dd745698f247be0 100644 (file)
@@ -156,7 +156,7 @@ int virNetDevExists(const char *brname)
 
 int virNetDevSetOnline(const char *ifname,
                        bool online)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_MOCKABLE;
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NOINLINE;
 int virNetDevGetOnline(const char *ifname,
                       bool *online)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
@@ -164,7 +164,7 @@ int virNetDevGetOnline(const char *ifname,
 
 int virNetDevSetMAC(const char *ifname,
                     const virMacAddr *macaddr)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_MOCKABLE;
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NOINLINE;
 int virNetDevGetMAC(const char *ifname,
                     virMacAddrPtr macaddr)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
@@ -303,8 +303,8 @@ int virNetDevSysfsFile(char **pf_sysfs_device_link,
                        const char *ifname,
                        const char *file)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
-    ATTRIBUTE_RETURN_CHECK ATTRIBUTE_MOCKABLE;
+    ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NOINLINE;
 
 int virNetDevRunEthernetScript(const char *ifname, const char *script)
-    ATTRIBUTE_MOCKABLE;
+    ATTRIBUTE_NOINLINE;
 #endif /* __VIR_NETDEV_H__ */
index 972a49ae8f1a422d52be5f1b3f96231bba9e3ef0..6b509ea445ac204782ce50bf505a156474e0020b 100644 (file)
@@ -67,7 +67,7 @@ int virNetDevIPAddrAdd(const char *ifname,
                        virSocketAddr *addr,
                        virSocketAddr *peer,
                        unsigned int prefix)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_MOCKABLE;
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NOINLINE;
 int virNetDevIPRouteAdd(const char *ifname,
                         virSocketAddrPtr addr,
                         unsigned int prefix,
index dc677ca0248c1e9317ae4bb0fc26d12a62f102bf..51bb1dd006b9e2e6328925b2f2bb5131136b3ccf 100644 (file)
@@ -59,6 +59,6 @@ int virNetDevOpenvswitchInterfaceStats(const char *ifname,
 
 int virNetDevOpenvswitchGetVhostuserIfname(const char *path,
                                            char **ifname)
-    ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_MOCKABLE;
+    ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NOINLINE;
 
 #endif /* __VIR_NETDEV_OPENVSWITCH_H__ */
index 1c4343ef80373ef0bd1e43f918bab690683028f1..0b17feb8d94d0306598f8de8247fca251c235ade 100644 (file)
@@ -39,7 +39,7 @@ int virNetDevTapCreate(char **ifname,
                        int *tapfd,
                        size_t tapfdSize,
                        unsigned int flags)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_MOCKABLE;
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NOINLINE;
 
 int virNetDevTapDelete(const char *ifname,
                        const char *tunpath)
@@ -49,7 +49,7 @@ int virNetDevTapGetName(int tapfd, char **ifname)
     ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
 
 char* virNetDevTapGetRealDeviceName(char *ifname)
-      ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_MOCKABLE;
+      ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NOINLINE;
 
 typedef enum {
    VIR_NETDEV_TAP_CREATE_NONE = 0,
@@ -89,7 +89,7 @@ int virNetDevTapCreateInBridgePort(const char *brname,
                                    unsigned int *actualMTU,
                                    unsigned int flags)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
-    ATTRIBUTE_RETURN_CHECK ATTRIBUTE_MOCKABLE;
+    ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NOINLINE;
 
 int virNetDevTapInterfaceStats(const char *ifname,
                                virDomainInterfaceStatsPtr stats)
index 62b89e9cb7b07a8f048176c4cf4ca344dcf11a03..e4e1fd0b9755989d590312096a72f0837e3ce5e7 100644 (file)
@@ -34,20 +34,20 @@ int virNumaSetupMemoryPolicy(virDomainNumatuneMemMode mode,
                              virBitmapPtr nodeset);
 
 virBitmapPtr virNumaGetHostMemoryNodeset(void);
-bool virNumaNodesetIsAvailable(virBitmapPtr nodeset) ATTRIBUTE_MOCKABLE;
-bool virNumaIsAvailable(void) ATTRIBUTE_MOCKABLE;
-int virNumaGetMaxNode(void) ATTRIBUTE_MOCKABLE;
-bool virNumaNodeIsAvailable(int node) ATTRIBUTE_MOCKABLE;
+bool virNumaNodesetIsAvailable(virBitmapPtr nodeset) ATTRIBUTE_NOINLINE;
+bool virNumaIsAvailable(void) ATTRIBUTE_NOINLINE;
+int virNumaGetMaxNode(void) ATTRIBUTE_NOINLINE;
+bool virNumaNodeIsAvailable(int node) ATTRIBUTE_NOINLINE;
 int virNumaGetDistances(int node,
                         int **distances,
-                        int *ndistances) ATTRIBUTE_MOCKABLE;
+                        int *ndistances) ATTRIBUTE_NOINLINE;
 int virNumaGetNodeMemory(int node,
                          unsigned long long *memsize,
-                         unsigned long long *memfree) ATTRIBUTE_MOCKABLE;
+                         unsigned long long *memfree) ATTRIBUTE_NOINLINE;
 
 unsigned int virNumaGetMaxCPUs(void);
 
-int virNumaGetNodeCPUs(int node, virBitmapPtr *cpus) ATTRIBUTE_MOCKABLE;
+int virNumaGetNodeCPUs(int node, virBitmapPtr *cpus) ATTRIBUTE_NOINLINE;
 
 int virNumaGetPageInfo(int node,
                        unsigned int page_size,
@@ -59,7 +59,7 @@ int virNumaGetPages(int node,
                     unsigned int **pages_avail,
                     unsigned int **pages_free,
                     size_t *npages)
-    ATTRIBUTE_NONNULL(5) ATTRIBUTE_MOCKABLE;
+    ATTRIBUTE_NONNULL(5) ATTRIBUTE_NOINLINE;
 int virNumaSetPagePoolSize(int node,
                            unsigned int page_size,
                            unsigned long long page_count,
index 990a456addf7da62467a259692b83af84482a4c4..7a984ee7b09eb3705f63c4eff256ccadeaa9f348 100644 (file)
 
 # include "internal.h"
 
-uint64_t virRandomBits(int nbits) ATTRIBUTE_MOCKABLE;
+uint64_t virRandomBits(int nbits) ATTRIBUTE_NOINLINE;
 double virRandom(void);
 uint32_t virRandomInt(uint32_t max);
 int virRandomBytes(unsigned char *buf, size_t buflen)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_MOCKABLE;
-int virRandomGenerateWWN(char **wwn, const char *virt_type) ATTRIBUTE_MOCKABLE;
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NOINLINE;
+int virRandomGenerateWWN(char **wwn, const char *virt_type) ATTRIBUTE_NOINLINE;
 
 #endif /* __VIR_RANDOM_H__ */
index eed563d6c7729c3a4abd688594fe7d5448ee359f..9f8b3ecf1e6409f941b9d2ff07e8d318ee3f5c75 100644 (file)
@@ -37,7 +37,7 @@ char *virSCSIDeviceGetSgName(const char *sysfs_prefix,
                              const char *adapter,
                              unsigned int bus,
                              unsigned int target,
-                             unsigned long long unit) ATTRIBUTE_MOCKABLE;
+                             unsigned long long unit) ATTRIBUTE_NOINLINE;
 char *virSCSIDeviceGetDevName(const char *sysfs_prefix,
                               const char *adapter,
                               unsigned int bus,
index f9272a659f577989da8b1f596b35a1186b381a97..21887ddbd5d49500b4c427bed19c18e58872edd2 100644 (file)
@@ -61,6 +61,6 @@ void virSCSIVHostDeviceGetUsedBy(virSCSIVHostDevicePtr dev,
                                  const char **drv_name,
                                  const char **dom_name);
 void virSCSIVHostDeviceFree(virSCSIVHostDevicePtr dev);
-int virSCSIVHostOpenVhostSCSI(int *vhostfd) ATTRIBUTE_MOCKABLE;
+int virSCSIVHostOpenVhostSCSI(int *vhostfd) ATTRIBUTE_NOINLINE;
 
 #endif /* __VIR_SCSIHOST_H__ */
index 7067bb53dedccebdf717a9d79947e9c1b3865e1d..b21fc0532f8df09b37073b15462bab212d4d4d41 100644 (file)
@@ -22,6 +22,6 @@
 #ifndef __VIR_TPM_H__
 # define __VIR_TPM_H__
 
-char *virTPMCreateCancelPath(const char *devpath) ATTRIBUTE_MOCKABLE;
+char *virTPMCreateCancelPath(const char *devpath) ATTRIBUTE_NOINLINE;
 
 #endif /* __VIR_TPM_H__ */
index 35e5ca3ab64891eeb77c413dc8b1c29ef3317830..49382557f6d6292c8bda5087b8c096bd0f246dd3 100644 (file)
@@ -139,8 +139,8 @@ char *virGetUserConfigDirectory(void);
 char *virGetUserCacheDirectory(void);
 char *virGetUserRuntimeDirectory(void);
 char *virGetUserShell(uid_t uid);
-char *virGetUserName(uid_t uid) ATTRIBUTE_MOCKABLE;
-char *virGetGroupName(gid_t gid) ATTRIBUTE_MOCKABLE;
+char *virGetUserName(uid_t uid) ATTRIBUTE_NOINLINE;
+char *virGetGroupName(gid_t gid) ATTRIBUTE_NOINLINE;
 int virGetGroupList(uid_t uid, gid_t group, gid_t **groups)
     ATTRIBUTE_NONNULL(3);
 int virGetUserID(const char *name,
@@ -201,12 +201,12 @@ verify((int)VIR_TRISTATE_BOOL_ABSENT == (int)VIR_TRISTATE_SWITCH_ABSENT);
 
 unsigned int virGetListenFDs(void);
 
-long virGetSystemPageSize(void) ATTRIBUTE_MOCKABLE;
-long virGetSystemPageSizeKB(void) ATTRIBUTE_MOCKABLE;
+long virGetSystemPageSize(void) ATTRIBUTE_NOINLINE;
+long virGetSystemPageSizeKB(void) ATTRIBUTE_NOINLINE;
 
 unsigned long long virMemoryLimitTruncate(unsigned long long value);
 bool virMemoryLimitIsSet(unsigned long long value);
-unsigned long long virMemoryMaxValue(bool ulong) ATTRIBUTE_MOCKABLE;
+unsigned long long virMemoryMaxValue(bool ulong) ATTRIBUTE_NOINLINE;
 
 /**
  * VIR_ASSIGN_IS_OVERFLOW:
index 3b41b4205087bf88040980a073950504e7fdf829..1d67e9ee57ea4276ea2806a6ca59549827c7e9b8 100644 (file)
@@ -49,7 +49,7 @@ int virGetHostUUID(unsigned char *host_uuid) ATTRIBUTE_NONNULL(1);
 
 int virUUIDIsValid(unsigned char *uuid);
 
-int virUUIDGenerate(unsigned char *uuid) ATTRIBUTE_MOCKABLE;
+int virUUIDGenerate(unsigned char *uuid) ATTRIBUTE_NOINLINE;
 
 int virUUIDParse(const char *uuidstr,
                  unsigned char *uuid)