/root/src/xen/xen/common/version.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include <xen/compile.h> |
2 | | #include <xen/init.h> |
3 | | #include <xen/errno.h> |
4 | | #include <xen/lib.h> |
5 | | #include <xen/string.h> |
6 | | #include <xen/types.h> |
7 | | #include <xen/efi.h> |
8 | | #include <xen/elf.h> |
9 | | #include <xen/version.h> |
10 | | |
11 | | #include <asm/cache.h> |
12 | | |
13 | | const char *xen_compile_date(void) |
14 | 1 | { |
15 | 1 | return XEN_COMPILE_DATE; |
16 | 1 | } |
17 | | |
18 | | const char *xen_compile_time(void) |
19 | 0 | { |
20 | 0 | return XEN_COMPILE_TIME; |
21 | 0 | } |
22 | | |
23 | | const char *xen_compile_by(void) |
24 | 1 | { |
25 | 1 | return XEN_COMPILE_BY; |
26 | 1 | } |
27 | | |
28 | | const char *xen_compile_domain(void) |
29 | 1 | { |
30 | 1 | return XEN_COMPILE_DOMAIN; |
31 | 1 | } |
32 | | |
33 | | const char *xen_compile_host(void) |
34 | 0 | { |
35 | 0 | return XEN_COMPILE_HOST; |
36 | 0 | } |
37 | | |
38 | | const char *xen_compiler(void) |
39 | 1 | { |
40 | 1 | return XEN_COMPILER; |
41 | 1 | } |
42 | | |
43 | | unsigned int xen_major_version(void) |
44 | 3 | { |
45 | 3 | return XEN_VERSION; |
46 | 3 | } |
47 | | |
48 | | unsigned int xen_minor_version(void) |
49 | 3 | { |
50 | 3 | return XEN_SUBVERSION; |
51 | 3 | } |
52 | | |
53 | | const char *xen_extra_version(void) |
54 | 1 | { |
55 | 1 | return XEN_EXTRAVERSION; |
56 | 1 | } |
57 | | |
58 | | const char *xen_changeset(void) |
59 | 1 | { |
60 | 1 | return XEN_CHANGESET; |
61 | 1 | } |
62 | | |
63 | | const char *xen_banner(void) |
64 | 1 | { |
65 | 1 | return XEN_BANNER; |
66 | 1 | } |
67 | | |
68 | | const char *xen_deny(void) |
69 | 0 | { |
70 | 0 | return "<denied>"; |
71 | 0 | } |
72 | | |
73 | | static const void *build_id_p __read_mostly; |
74 | | static unsigned int build_id_len __read_mostly; |
75 | | |
76 | | int xen_build_id(const void **p, unsigned int *len) |
77 | 0 | { |
78 | 0 | if ( !build_id_len ) |
79 | 0 | return -ENODATA; |
80 | 0 |
|
81 | 0 | *len = build_id_len; |
82 | 0 | *p = build_id_p; |
83 | 0 |
|
84 | 0 | return 0; |
85 | 0 | } |
86 | | |
87 | | #ifdef BUILD_ID |
88 | | /* Defined in linker script. */ |
89 | | extern const Elf_Note __note_gnu_build_id_start[], __note_gnu_build_id_end[]; |
90 | | |
91 | | int xen_build_id_check(const Elf_Note *n, unsigned int n_sz, |
92 | | const void **p, unsigned int *len) |
93 | | { |
94 | | /* Check if we really have a build-id. */ |
95 | | ASSERT(n_sz > sizeof(*n)); |
96 | | |
97 | | if ( NT_GNU_BUILD_ID != n->type ) |
98 | | return -ENODATA; |
99 | | |
100 | | if ( n->namesz + n->descsz < n->namesz ) |
101 | | return -EINVAL; |
102 | | |
103 | | if ( n->namesz < 4 /* GNU\0 */) |
104 | | return -EINVAL; |
105 | | |
106 | | if ( n->namesz + n->descsz > n_sz - sizeof(*n) ) |
107 | | return -EINVAL; |
108 | | |
109 | | /* Sanity check, name should be "GNU" for ld-generated build-id. */ |
110 | | if ( strncmp(ELFNOTE_NAME(n), "GNU", n->namesz) != 0 ) |
111 | | return -ENODATA; |
112 | | |
113 | | if ( len ) |
114 | | *len = n->descsz; |
115 | | if ( p ) |
116 | | *p = ELFNOTE_DESC(n); |
117 | | |
118 | | return 0; |
119 | | } |
120 | | |
121 | | struct pe_external_debug_directory |
122 | | { |
123 | | uint32_t characteristics; |
124 | | uint32_t time_stamp; |
125 | | uint16_t major_version; |
126 | | uint16_t minor_version; |
127 | | #define PE_IMAGE_DEBUG_TYPE_CODEVIEW 2 |
128 | | uint32_t type; |
129 | | uint32_t size; |
130 | | uint32_t rva_of_data; |
131 | | uint32_t filepos_of_data; |
132 | | }; |
133 | | |
134 | | struct cv_info_pdb70 |
135 | | { |
136 | | #define CVINFO_PDB70_CVSIGNATURE 0x53445352 /* "RSDS" */ |
137 | | uint32_t cv_signature; |
138 | | unsigned char signature[16]; |
139 | | uint32_t age; |
140 | | char pdb_filename[]; |
141 | | }; |
142 | | |
143 | | static int __init xen_build_init(void) |
144 | | { |
145 | | const Elf_Note *n = __note_gnu_build_id_start; |
146 | | unsigned int sz; |
147 | | int rc; |
148 | | |
149 | | /* --build-id invoked with wrong parameters. */ |
150 | | if ( __note_gnu_build_id_end <= &n[0] ) |
151 | | return -ENODATA; |
152 | | |
153 | | /* Check for full Note header. */ |
154 | | if ( &n[1] >= __note_gnu_build_id_end ) |
155 | | return -ENODATA; |
156 | | |
157 | | sz = (void *)__note_gnu_build_id_end - (void *)n; |
158 | | |
159 | | rc = xen_build_id_check(n, sz, &build_id_p, &build_id_len); |
160 | | |
161 | | #ifdef CONFIG_X86 |
162 | | /* Alternatively we may have a CodeView record from an EFI build. */ |
163 | | if ( rc && efi_enabled(EFI_LOADER) ) |
164 | | { |
165 | | const struct pe_external_debug_directory *dir = (const void *)n; |
166 | | |
167 | | /* |
168 | | * Validate that the full-note-header check above won't prevent |
169 | | * fall-through to the CodeView case here. |
170 | | */ |
171 | | BUILD_BUG_ON(sizeof(*n) > sizeof(*dir)); |
172 | | |
173 | | if ( sz > sizeof(*dir) + sizeof(struct cv_info_pdb70) && |
174 | | dir->type == PE_IMAGE_DEBUG_TYPE_CODEVIEW && |
175 | | dir->size > sizeof(struct cv_info_pdb70) && |
176 | | XEN_VIRT_START + dir->rva_of_data == (unsigned long)(dir + 1) ) |
177 | | { |
178 | | const struct cv_info_pdb70 *info = (const void *)(dir + 1); |
179 | | |
180 | | if ( info->cv_signature == CVINFO_PDB70_CVSIGNATURE ) |
181 | | { |
182 | | build_id_p = info->signature; |
183 | | build_id_len = sizeof(info->signature); |
184 | | rc = 0; |
185 | | } |
186 | | } |
187 | | } |
188 | | #endif |
189 | | if ( !rc ) |
190 | | printk(XENLOG_INFO "build-id: %*phN\n", build_id_len, build_id_p); |
191 | | |
192 | | return rc; |
193 | | } |
194 | | __initcall(xen_build_init); |
195 | | #endif |
196 | | /* |
197 | | * Local variables: |
198 | | * mode: C |
199 | | * c-file-style: "BSD" |
200 | | * c-basic-offset: 4 |
201 | | * tab-width: 4 |
202 | | * indent-tabs-mode: nil |
203 | | * End: |
204 | | */ |