• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
Build has been canceled!

systemd / systemd / 14630481637

23 Apr 2025 07:04PM UTC coverage: 72.178% (-0.002%) from 72.18%
14630481637

push

github

DaanDeMeyer
mkosi: Run clangd within the tools tree instead of the build container

Running within the build sandbox has a number of disadvantages:
- We have a separate clangd cache for each distribution/release combo
- It requires to build the full image before clangd can be used
- It breaks every time the image becomes out of date and requires a
  rebuild
- We can't look at system headers as we don't have the knowledge to map
  them from inside the build sandbox to the corresponding path on the host

Instead, let's have mkosi.clangd run clangd within the tools tree. We
already require building systemd for both the host and the target anyway,
and all the dependencies to build systemd are installed in the tools tree
already for that, as well as clangd since it's installed together with the
other clang tooling we install in the tools tree. Unlike the previous approach,
this approach only requires the mkosi tools tree to be built upfront, which has
a much higher chance of not invalidating its cache. We can also trivially map
system header lookups from within the sandbox to the path within mkosi.tools
on the host so that starts working as well.

297054 of 411557 relevant lines covered (72.18%)

686269.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.75
/src/basic/macro.h
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
#pragma once
3

4
#include <assert.h>
5
#include <errno.h>
6
#include <inttypes.h>
7
#include <stdbool.h>
8
#include <sys/param.h>
9
#include <sys/sysmacros.h>
10
#include <sys/types.h>
11

12
#include "constants.h"
13
#include "macro-fundamental.h"
14

15
/* Note: on GCC "no_sanitize_address" is a function attribute only, on llvm it may also be applied to global
16
 * variables. We define a specific macro which knows this. Note that on GCC we don't need this decorator so much, since
17
 * our primary use case for this attribute is registration structures placed in named ELF sections which shall not be
18
 * padded, but GCC doesn't pad those anyway if AddressSanitizer is enabled. */
19
#if HAS_FEATURE_ADDRESS_SANITIZER && defined(__clang__)
20
#define _variable_no_sanitize_address_ __attribute__((__no_sanitize_address__))
21
#else
22
#define _variable_no_sanitize_address_
23
#endif
24

25
/* Apparently there's no has_feature() call defined to check for ubsan, hence let's define this
26
 * unconditionally on llvm */
27
#if defined(__clang__)
28
#define _function_no_sanitize_float_cast_overflow_ __attribute__((no_sanitize("float-cast-overflow")))
29
#else
30
#define _function_no_sanitize_float_cast_overflow_
31
#endif
32

33
/* test harness */
34
#define EXIT_TEST_SKIP 77
35

36
/* builtins */
37
#if __SIZEOF_INT__ == 4
38
#define BUILTIN_FFS_U32(x) __builtin_ffs(x);
39
#elif __SIZEOF_LONG__ == 4
40
#define BUILTIN_FFS_U32(x) __builtin_ffsl(x);
41
#else
42
#error "neither int nor long are four bytes long?!?"
43
#endif
44

45
static inline uint64_t u64_multiply_safe(uint64_t a, uint64_t b) {
776✔
46
        if (_unlikely_(a != 0 && b > (UINT64_MAX / a)))
776✔
47
                return 0; /* overflow */
48

49
        return a * b;
776✔
50
}
51

52
/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */
53
static inline unsigned long ALIGN_POWER2(unsigned long u) {
42,980,021✔
54

55
        /* Avoid subtraction overflow */
56
        if (u == 0)
42,980,021✔
57
                return 0;
58

59
        /* clz(0) is undefined */
60
        if (u == 1)
42,980,021✔
61
                return 1;
62

63
        /* left-shift overflow is undefined */
64
        if (__builtin_clzl(u - 1UL) < 1)
42,980,020✔
65
                return 0;
66

67
        return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL));
42,978,996✔
68
}
69

70
static inline size_t GREEDY_ALLOC_ROUND_UP(size_t l) {
44,638,175✔
71
        size_t m;
44,638,175✔
72

73
        /* Round up allocation sizes a bit to some reasonable, likely larger value. This is supposed to be
74
         * used for cases which are likely called in an allocation loop of some form, i.e. that repetitively
75
         * grow stuff, for example strv_extend() and suchlike.
76
         *
77
         * Note the difference to GREEDY_REALLOC() here, as this helper operates on a single size value only,
78
         * and rounds up to next multiple of 2, needing no further counter.
79
         *
80
         * Note the benefits of direct ALIGN_POWER2() usage: type-safety for size_t, sane handling for very
81
         * small (i.e. <= 2) and safe handling for very large (i.e. > SSIZE_MAX) values. */
82

83
        if (l <= 2)
44,638,175✔
84
                return 2; /* Never allocate less than 2 of something.  */
85

86
        m = ALIGN_POWER2(l);
42,847,927✔
87
        if (m == 0) /* overflow? */
42,847,927✔
88
                return l;
×
89

90
        return m;
91
}
92

93
/*
94
 * container_of - cast a member of a structure out to the containing structure
95
 * @ptr: the pointer to the member.
96
 * @type: the type of the container struct this is embedded in.
97
 * @member: the name of the member within the struct.
98
 */
99
#define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member)
100
#define __container_of(uniq, ptr, type, member)                         \
101
        ({                                                              \
102
                const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \
103
                (type*)( (char *)UNIQ_T(A, uniq) - offsetof(type, member) ); \
104
        })
105

106
#define return_with_errno(r, err)                     \
107
        do {                                          \
108
                errno = abs(err);                     \
109
                return r;                             \
110
        } while (false)
111

112
#define PTR_TO_INT(p) ((int) ((intptr_t) (p)))
113
#define INT_TO_PTR(u) ((void *) ((intptr_t) (u)))
114
#define PTR_TO_UINT(p) ((unsigned) ((uintptr_t) (p)))
115
#define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u)))
116

117
#define PTR_TO_LONG(p) ((long) ((intptr_t) (p)))
118
#define LONG_TO_PTR(u) ((void *) ((intptr_t) (u)))
119
#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
120
#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
121

122
#define PTR_TO_UINT8(p) ((uint8_t) ((uintptr_t) (p)))
123
#define UINT8_TO_PTR(u) ((void *) ((uintptr_t) (u)))
124

125
#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
126
#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u)))
127
#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
128
#define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u)))
129

130
#define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p)))
131
#define INT64_TO_PTR(u) ((void *) ((intptr_t) (u)))
132
#define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p)))
133
#define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u)))
134

135
#define CHAR_TO_STR(x) ((char[2]) { x, 0 })
136

137
#define char_array_0(x) x[sizeof(x)-1] = 0;
138

139
/* Maximum buffer size needed for formatting an unsigned integer type as hex, including space for '0x'
140
 * prefix and trailing NUL suffix. */
141
#define HEXADECIMAL_STR_MAX(type) (2 + sizeof(type) * 2 + 1)
142

143
/* Returns the number of chars needed to format variables of the specified type as a decimal string. Adds in
144
 * extra space for a negative '-' prefix for signed types. Includes space for the trailing NUL. */
145
#define DECIMAL_STR_MAX(type)                                           \
146
        ((size_t) IS_SIGNED_INTEGER_TYPE(type) + 1U +                   \
147
            (sizeof(type) <= 1 ? 3U :                                   \
148
             sizeof(type) <= 2 ? 5U :                                   \
149
             sizeof(type) <= 4 ? 10U :                                  \
150
             sizeof(type) <= 8 ? (IS_SIGNED_INTEGER_TYPE(type) ? 19U : 20U) : sizeof(int[-2*(sizeof(type) > 8)])))
151

152
/* Returns the number of chars needed to format the specified integer value. It's hence more specific than
153
 * DECIMAL_STR_MAX() which answers the same question for all possible values of the specified type. Does
154
 * *not* include space for a trailing NUL. (If you wonder why we special case _x_ == 0 here: it's to trick
155
 * out gcc's -Wtype-limits, which would complain on comparing an unsigned type with < 0, otherwise. By
156
 * special-casing == 0 here first, we can use <= 0 instead of < 0 to trick out gcc.) */
157
#define DECIMAL_STR_WIDTH(x)                                      \
158
        ({                                                        \
159
                typeof(x) _x_ = (x);                              \
160
                size_t ans;                                       \
161
                if (_x_ == 0)                                     \
162
                        ans = 1;                                  \
163
                else {                                            \
164
                        ans = _x_ <= 0 ? 2 : 1;                   \
165
                        while ((_x_ /= 10) != 0)                  \
166
                                ans++;                            \
167
                }                                                 \
168
                ans;                                              \
169
        })
170

171
#define SWAP_TWO(x, y) do {                        \
172
                typeof(x) _t = (x);                \
173
                (x) = (y);                         \
174
                (y) = (_t);                        \
175
        } while (false)
176

177
#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL }))
178
#define STRV_MAKE_EMPTY ((char*[1]) { NULL })
179
#define STRV_MAKE_CONST(...) ((const char* const*) ((const char*[]) { __VA_ARGS__, NULL }))
180

181
/* Pointers range from NULL to POINTER_MAX */
182
#define POINTER_MAX ((void*) UINTPTR_MAX)
183

184
/* A macro to force copying of a variable from memory. This is useful whenever we want to read something from
185
 * memory and want to make sure the compiler won't optimize away the destination variable for us. It's not
186
 * supposed to be a full CPU memory barrier, i.e. CPU is still allowed to reorder the reads, but it is not
187
 * allowed to remove our local copies of the variables. We want this to work for unaligned memory, hence
188
 * memcpy() is great for our purposes. */
189
#define READ_NOW(x)                                                     \
190
        ({                                                              \
191
                typeof(x) _copy;                                        \
192
                memcpy(&_copy, &(x), sizeof(_copy));                    \
193
                asm volatile ("" : : : "memory");                       \
194
                _copy;                                                  \
195
        })
196

197
#define saturate_add(x, y, limit)                                       \
198
        ({                                                              \
199
                typeof(limit) _x = (x);                                 \
200
                typeof(limit) _y = (y);                                 \
201
                _x > (limit) || _y >= (limit) - _x ? (limit) : _x + _y; \
202
        })
203

204
static inline size_t size_add(size_t x, size_t y) {
567✔
205
        return saturate_add(x, y, SIZE_MAX);
722✔
206
}
207

208
/* A little helper for subtracting 1 off a pointer in a safe UB-free way. This is intended to be used for
209
 * loops that count down from a high pointer until some base. A naive loop would implement this like this:
210
 *
211
 * for (p = end-1; p >= base; p--) …
212
 *
213
 * But this is not safe because p before the base is UB in C. With this macro the loop becomes this instead:
214
 *
215
 * for (p = PTR_SUB1(end, base); p; p = PTR_SUB1(p, base)) …
216
 *
217
 * And is free from UB! */
218
#define PTR_SUB1(p, base)                                \
219
        ({                                               \
220
                typeof(p) _q = (p);                      \
221
                _q && _q > (base) ? &_q[-1] : NULL;      \
222
        })
223

224
/* Iterate through each argument passed. All must be the same type as 'entry' or must be implicitly
225
 * convertible. The iteration variable 'entry' must already be defined. */
226
#define FOREACH_ARGUMENT(entry, ...)                                     \
227
        _FOREACH_ARGUMENT(entry, UNIQ_T(_entries_, UNIQ), UNIQ_T(_current_, UNIQ), UNIQ_T(_va_sentinel_, UNIQ), ##__VA_ARGS__)
228
#define _FOREACH_ARGUMENT(entry, _entries_, _current_, _va_sentinel_, ...)      \
229
        for (typeof(entry) _va_sentinel_[1] = {}, _entries_[] = { __VA_ARGS__ __VA_OPT__(,) _va_sentinel_[0] }, *_current_ = _entries_; \
230
             ((long)(_current_ - _entries_) < (long)(ELEMENTSOF(_entries_) - 1)) && ({ entry = *_current_; true; }); \
231
             _current_++)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc