1 | // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) |
2 | |
3 | /* |
4 | * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org> |
5 | * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com> |
6 | * Copyright (C) 2015 Huawei Inc. |
7 | * Copyright (C) 2017 Nicira, Inc. |
8 | */ |
9 | |
10 | #undef _GNU_SOURCE |
11 | #include <stdio.h> |
12 | #include <string.h> |
13 | |
14 | #include "libbpf.h" |
15 | #include "libbpf_internal.h" |
16 | |
17 | /* make sure libbpf doesn't use kernel-only integer typedefs */ |
18 | #pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64 |
19 | |
20 | #define ERRNO_OFFSET(e) ((e) - __LIBBPF_ERRNO__START) |
21 | #define ERRCODE_OFFSET(c) ERRNO_OFFSET(LIBBPF_ERRNO__##c) |
22 | #define NR_ERRNO (__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START) |
23 | |
24 | static const char *libbpf_strerror_table[NR_ERRNO] = { |
25 | [ERRCODE_OFFSET(LIBELF)] = "Something wrong in libelf" , |
26 | [ERRCODE_OFFSET(FORMAT)] = "BPF object format invalid" , |
27 | [ERRCODE_OFFSET(KVERSION)] = "'version' section incorrect or lost" , |
28 | [ERRCODE_OFFSET(ENDIAN)] = "Endian mismatch" , |
29 | [ERRCODE_OFFSET(INTERNAL)] = "Internal error in libbpf" , |
30 | [ERRCODE_OFFSET(RELOC)] = "Relocation failed" , |
31 | [ERRCODE_OFFSET(VERIFY)] = "Kernel verifier blocks program loading" , |
32 | [ERRCODE_OFFSET(PROG2BIG)] = "Program too big" , |
33 | [ERRCODE_OFFSET(KVER)] = "Incorrect kernel version" , |
34 | [ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type" , |
35 | [ERRCODE_OFFSET(WRNGPID)] = "Wrong pid in netlink message" , |
36 | [ERRCODE_OFFSET(INVSEQ)] = "Invalid netlink sequence" , |
37 | [ERRCODE_OFFSET(NLPARSE)] = "Incorrect netlink message parsing" , |
38 | }; |
39 | |
40 | int libbpf_strerror(int err, char *buf, size_t size) |
41 | { |
42 | int ret; |
43 | |
44 | if (!buf || !size) |
45 | return libbpf_err(ret: -EINVAL); |
46 | |
47 | err = err > 0 ? err : -err; |
48 | |
49 | if (err < __LIBBPF_ERRNO__START) { |
50 | ret = strerror_r(err, buf, size); |
51 | buf[size - 1] = '\0'; |
52 | return libbpf_err_errno(ret); |
53 | } |
54 | |
55 | if (err < __LIBBPF_ERRNO__END) { |
56 | const char *msg; |
57 | |
58 | msg = libbpf_strerror_table[ERRNO_OFFSET(err)]; |
59 | ret = snprintf(buf, size, fmt: "%s" , msg); |
60 | buf[size - 1] = '\0'; |
61 | /* The length of the buf and msg is positive. |
62 | * A negative number may be returned only when the |
63 | * size exceeds INT_MAX. Not likely to appear. |
64 | */ |
65 | if (ret >= size) |
66 | return libbpf_err(ret: -ERANGE); |
67 | return 0; |
68 | } |
69 | |
70 | ret = snprintf(buf, size, fmt: "Unknown libbpf error %d" , err); |
71 | buf[size - 1] = '\0'; |
72 | if (ret >= size) |
73 | return libbpf_err(ret: -ERANGE); |
74 | return libbpf_err(ret: -ENOENT); |
75 | } |
76 | |