blob: 54a676f77a4e5ed9b44d434e29e0ec6907ae6782 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (c) 2013 Google, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#include <lib/buildsig.h>
24
25#include <debug.h>
26#include <err.h>
27#include <stdint.h>
28#include <stdio.h>
29#include <string.h>
30#include <compiler.h>
31#include <lib/version.h>
32
33#define MAGIC ((uint32_t)'BSIG')
34#define MAGIC2 (~MAGIC)
35#define MAGIC3 ((uint32_t)'BSG2')
36
37struct buildsig {
38 uint32_t magic;
39
40 const lk_version_t *version;
41
42 uint32_t magic2;
43
44 uint32_t buildtype;
45 uint32_t start;
46 uint32_t end;
47 uint32_t crc32;
48
49 uint32_t magic3;
50};
51
52extern char __rom_start;
53extern char __rom_end;
54
55const struct buildsig buildsig __SECTION(".text.boot") = {
56 .magic = MAGIC,
57 .version = &version,
58 .magic2 = MAGIC2,
59#if WITH_APP_BOOTLOADER
60 .buildtype = 1, /* TODO: pull from systemwide headers */
61#else
62 .buildtype = 0,
63#endif
64 .start = (uint32_t)&__rom_start,
65 .end = (uint32_t)&__rom_end,
66 .crc32 = 0, /* filled in via an external tool */
67 .magic3 = MAGIC3
68};
69
70status_t buildsig_search(const void *_ptr, size_t search_len, size_t max_len, const lk_version_t **version)
71{
72 if (max_len < search_len)
73 return ERR_INVALID_ARGS;
74
75 if (max_len < sizeof(lk_version_t))
76 return ERR_INVALID_ARGS;
77
78 /* search for the build signature on 4 byte boundaries */
79 const uint32_t *ptr = _ptr;
80 for (size_t pos = 0; pos < search_len / 4; pos++) {
81 const struct buildsig *sig = (void *)&ptr[pos];
82
83 /* see if the buildsig's magic matches */
84 if (sig->magic != MAGIC || sig->magic2 != MAGIC2)
85 continue;
86
87 /* make sure the pointer to the version struct makes sense */
88 if ((size_t)sig->version - (size_t)ptr > max_len - sizeof(lk_version_t))
89 continue;
90
91 /* validate the strings in the version struct make sense */
92 /* ensure they lie within the search area (ptr .. ptr+max_len) */
93#define VALIDSTR(str) \
94 (((size_t)(str) >= (size_t)ptr) && (((size_t)(str) - (size_t)ptr) < max_len))
95 if (!VALIDSTR(sig->version->arch))
96 continue;
97 if (!VALIDSTR(sig->version->platform))
98 continue;
99 if (!VALIDSTR(sig->version->target))
100 continue;
101 if (!VALIDSTR(sig->version->project))
102 continue;
103 if (!VALIDSTR(sig->version->buildid))
104 continue;
105#undef VALIDSTR
106
107 *version = sig->version;
108 return NO_ERROR;
109 }
110
111 return ERR_NOT_FOUND;
112}
113
114#if WITH_LIB_CONSOLE
115
116#include <lib/console.h>
117
118extern char __rom_start;
119
120static int cmd_buildsig(int argc, const cmd_args *argv)
121{
122 if (argc < 2) {
123//notenoughargs:
124 printf("not enough args\n");
125usage:
126 printf("usage: %s dump [offset]\n", argv[0].str);
127 return -1;
128 }
129
130 if (!strcmp(argv[1].str, "dump")) {
131 const void *offset = &__rom_start;
132 if (argc >= 3) {
133 offset = argv[2].p;
134 }
135
136 const lk_version_t *v;
137 status_t err = buildsig_search(offset, DEFAULT_BUILDSIG_SEARCH_LEN, 256*1024, &v);
138 if (err < 0) {
139 printf("could not find build signature\n");
140 return ERR_NOT_FOUND;
141 }
142
143 printf("found signature:\n");
144 printf("\tarch: %s\n\tplatform: %s\n\ttarget: %s\n\tproject: %s\n\tbuildid: %s\n",
145 v->arch, v->platform, v->target, v->project, v->buildid);
146 } else {
147 goto usage;
148 }
149
150 return NO_ERROR;
151}
152
153
154STATIC_COMMAND_START
155#if LK_DEBUGLEVEL > 1
156 STATIC_COMMAND("buildsig", "scan for and dump build signature", &cmd_buildsig)
157#endif
158STATIC_COMMAND_END(buildid);
159
160#endif
161