1250549d3e742cddaf72b4f53d5739e54faf5db96Jay Srinivasan// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson// Use of this source code is governed by a BSD-style license that can be
3f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson// found in the LICENSE file.
4f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
5f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson#ifndef VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
6f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson#define VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
7f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
823429d3d782f7506fb4747356974294cce08ac47Bill Richardson#include <fcntl.h>
905987b159acb9737707b9ef92b818ac434ef8c3dDavid Riley#ifndef HAVE_MACOS
10f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson#include <features.h>
1105987b159acb9737707b9ef92b818ac434ef8c3dDavid Riley#endif
12f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson#include <stdint.h>
13c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson#include <stdio.h>
14c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson#include <stdlib.h>
154cb5497984642b8cbd592c14cb1912a787b2d4d7Bill Richardson#include "cgpt_endian.h"
16f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson#include "cgptlib.h"
174cb5497984642b8cbd592c14cb1912a787b2d4d7Bill Richardson#include "gpt.h"
18f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
19f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonstruct legacy_partition {
20f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint8_t  status;
21f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint8_t  f_head;
22f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint8_t  f_sect;
23f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint8_t  f_cyl;
24f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint8_t  type;
25f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint8_t  l_head;
26f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint8_t  l_sect;
27f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint8_t  l_cyl;
28f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint32_t f_lba;
29f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint32_t num_sect;
30f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson} __attribute__((packed));
31f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
32f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson// syslinux uses this format:
33f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonstruct pmbr {
34f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint8_t                 bootcode[424];
35f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  Guid                    boot_guid;
36f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint32_t                disk_id;
37f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint8_t                 magic[2];     // 0x1d, 0x9a
38f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  struct legacy_partition part[4];
39f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint8_t                 sig[2];       // 0x55, 0xaa
40f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson} __attribute__((packed));
41f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
42c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardsonvoid PMBRToStr(struct pmbr *pmbr, char *str, unsigned int buflen);
43f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
44f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson// Handle to the drive storing the GPT.
45f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonstruct drive {
46f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  uint64_t size;    /* total size (in bytes) */
47f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  GptData gpt;
48f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson  struct pmbr pmbr;
49ab899591808dd3e5f955ab7693b54a83389cd35fNam T. Nguyen  int fd;       /* file descriptor */
50f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson};
51f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
526ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen// Opens a block device or file, loads raw GPT data from it.
53ab899591808dd3e5f955ab7693b54a83389cd35fNam T. Nguyen// 'mode' should be O_RDONLY or O_RDWR.
54ab899591808dd3e5f955ab7693b54a83389cd35fNam T. Nguyen// If 'drive_size' is 0, both the partitions and GPT structs reside on the same
55ab899591808dd3e5f955ab7693b54a83389cd35fNam T. Nguyen// 'drive_path'.
56ab899591808dd3e5f955ab7693b54a83389cd35fNam T. Nguyen// Otherwise, 'drive_size' is taken as the size of the device that all
57ab899591808dd3e5f955ab7693b54a83389cd35fNam T. Nguyen// partitions will reside on, and 'drive_path' is where we store GPT structs.
586ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen//
596ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen// Returns CGPT_FAILED if any error happens.
60ab899591808dd3e5f955ab7693b54a83389cd35fNam T. Nguyen// Returns CGPT_OK if success and information are stored in 'drive'. */
61ab899591808dd3e5f955ab7693b54a83389cd35fNam T. Nguyenint DriveOpen(const char *drive_path, struct drive *drive, int mode,
62ab899591808dd3e5f955ab7693b54a83389cd35fNam T. Nguyen              uint64_t drive_size);
63f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonint DriveClose(struct drive *drive, int update_as_needed);
64f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonint CheckValid(const struct drive *drive);
65f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
66534723a6519267461855441279b321e6fc1e4e90Albert Chaulk/* Loads sectors from 'drive'.
67534723a6519267461855441279b321e6fc1e4e90Albert Chaulk * *buf is pointed to an allocated memory when returned, and should be
68534723a6519267461855441279b321e6fc1e4e90Albert Chaulk * freed.
69534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *
70534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *   drive -- open drive.
71534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *   buf -- pointer to buffer pointer
72534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *   sector -- offset of starting sector (in sectors)
73534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *   sector_bytes -- bytes per sector
74534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *   sector_count -- number of sectors to load
75534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *
76534723a6519267461855441279b321e6fc1e4e90Albert Chaulk * Returns CGPT_OK for successful. Aborts if any error occurs.
77534723a6519267461855441279b321e6fc1e4e90Albert Chaulk */
78534723a6519267461855441279b321e6fc1e4e90Albert Chaulkint Load(struct drive *drive, uint8_t **buf,
79534723a6519267461855441279b321e6fc1e4e90Albert Chaulk                const uint64_t sector,
80534723a6519267461855441279b321e6fc1e4e90Albert Chaulk                const uint64_t sector_bytes,
81534723a6519267461855441279b321e6fc1e4e90Albert Chaulk                const uint64_t sector_count);
82534723a6519267461855441279b321e6fc1e4e90Albert Chaulk
83534723a6519267461855441279b321e6fc1e4e90Albert Chaulk/* Saves sectors to 'drive'.
84534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *
85534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *   drive -- open drive
86534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *   buf -- pointer to buffer
87534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *   sector -- starting sector offset
88534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *   sector_bytes -- bytes per sector
89534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *   sector_count -- number of sector to save
90534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *
91534723a6519267461855441279b321e6fc1e4e90Albert Chaulk * Returns CGPT_OK for successful, CGPT_FAILED for failed.
92534723a6519267461855441279b321e6fc1e4e90Albert Chaulk */
93534723a6519267461855441279b321e6fc1e4e90Albert Chaulkint Save(struct drive *drive, const uint8_t *buf,
94534723a6519267461855441279b321e6fc1e4e90Albert Chaulk                const uint64_t sector,
95534723a6519267461855441279b321e6fc1e4e90Albert Chaulk                const uint64_t sector_bytes,
96534723a6519267461855441279b321e6fc1e4e90Albert Chaulk                const uint64_t sector_count);
97534723a6519267461855441279b321e6fc1e4e90Albert Chaulk
98534723a6519267461855441279b321e6fc1e4e90Albert Chaulk
99534723a6519267461855441279b321e6fc1e4e90Albert Chaulk/* GUID conversion functions. Accepted format:
100534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *
101534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *   "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
102534723a6519267461855441279b321e6fc1e4e90Albert Chaulk *
103534723a6519267461855441279b321e6fc1e4e90Albert Chaulk * At least GUID_STRLEN bytes should be reserved in 'str' (included the tailing
104534723a6519267461855441279b321e6fc1e4e90Albert Chaulk * '\0').
105534723a6519267461855441279b321e6fc1e4e90Albert Chaulk */
106534723a6519267461855441279b321e6fc1e4e90Albert Chaulk#define GUID_STRLEN 37
107534723a6519267461855441279b321e6fc1e4e90Albert Chaulkint StrToGuid(const char *str, Guid *guid);
108534723a6519267461855441279b321e6fc1e4e90Albert Chaulkvoid GuidToStr(const Guid *guid, char *str, unsigned int buflen);
109534723a6519267461855441279b321e6fc1e4e90Albert Chaulkint GuidEqual(const Guid *guid1, const Guid *guid2);
110534723a6519267461855441279b321e6fc1e4e90Albert Chaulkint IsZero(const Guid *guid);
111534723a6519267461855441279b321e6fc1e4e90Albert Chaulk
1123430b32667937a75c7a3afc83f8f7a601a8187f7Bill Richardson/* Constant global type values to compare against */
11393cf15e9a1c29962d6f08be6102d2ea7876d969fGabe Blackextern const Guid guid_chromeos_firmware;
1143430b32667937a75c7a3afc83f8f7a601a8187f7Bill Richardsonextern const Guid guid_chromeos_kernel;
1153430b32667937a75c7a3afc83f8f7a601a8187f7Bill Richardsonextern const Guid guid_chromeos_rootfs;
1163430b32667937a75c7a3afc83f8f7a601a8187f7Bill Richardsonextern const Guid guid_linux_data;
1173430b32667937a75c7a3afc83f8f7a601a8187f7Bill Richardsonextern const Guid guid_chromeos_reserved;
1183430b32667937a75c7a3afc83f8f7a601a8187f7Bill Richardsonextern const Guid guid_efi;
1193430b32667937a75c7a3afc83f8f7a601a8187f7Bill Richardsonextern const Guid guid_unused;
120f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
121f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonint ReadPMBR(struct drive *drive);
122f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonint WritePMBR(struct drive *drive);
123f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
124c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson/* Convert possibly unterminated UTF16 string to UTF8.
125c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson * Caller must prepare enough space for UTF8, which could be up to
126500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Lo * twice the byte length of UTF16 string plus the terminating '\0'.
127500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Lo *
128500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Lo * Return: CGPT_OK --- all character are converted successfully.
129500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Lo *         CGPT_FAILED --- convert error, i.e. output buffer is too short.
130f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson */
131500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Loint UTF16ToUTF8(const uint16_t *utf16, unsigned int maxinput,
132500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Lo                uint8_t *utf8, unsigned int maxoutput);
133500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Lo
134c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson/* Convert null-terminated UTF8 string to UTF16.
135500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Lo * Caller must prepare enough space for UTF16, which is the byte length of UTF8
136500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Lo * plus the terminating 0x0000.
137500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Lo *
138500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Lo * Return: CGPT_OK --- all character are converted successfully.
139500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Lo *         CGPT_FAILED --- convert error, i.e. output buffer is too short.
140f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson */
141500b3c2369e1a8370041ea276bc40b81c6e7a713Louis Yung-Chieh Loint UTF8ToUTF16(const uint8_t *utf8, uint16_t *utf16, unsigned int maxoutput);
142f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
143f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson/* Helper functions for supported GPT types. */
144f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonint ResolveType(const Guid *type, char *buf);
145f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonint SupportedType(const char *name, Guid *type);
146f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonvoid PrintTypes(void);
147c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardsonvoid EntryDetails(GptEntry *entry, uint32_t index, int raw);
148f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
149fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulkuint32_t GetNumberOfEntries(const struct drive *drive);
150c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill RichardsonGptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index);
151b334e651a597a10d562bc882613f0b482b24e3caAlbert Chaulk
152fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulkvoid SetPriority(struct drive *drive, int secondary, uint32_t entry_index,
153c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson                 int priority);
154fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulkint GetPriority(struct drive *drive, int secondary, uint32_t entry_index);
155fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulkvoid SetTries(struct drive *drive, int secondary, uint32_t entry_index,
156fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulk              int tries);
157fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulkint GetTries(struct drive *drive, int secondary, uint32_t entry_index);
158fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulkvoid SetSuccessful(struct drive *drive, int secondary, uint32_t entry_index,
159c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson                   int success);
160fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulkint GetSuccessful(struct drive *drive, int secondary, uint32_t entry_index);
161fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulk
162fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulkvoid SetRaw(struct drive *drive, int secondary, uint32_t entry_index,
163fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulk           uint32_t raw);
164fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulk
165fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulkvoid UpdateAllEntries(struct drive *drive);
166f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
167f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonuint8_t RepairHeader(GptData *gpt, const uint32_t valid_headers);
168f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonuint8_t RepairEntries(GptData *gpt, const uint32_t valid_entries);
169f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonvoid UpdateCrc(GptData *gpt);
170f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonint IsSynonymous(const GptHeader* a, const GptHeader* b);
171f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
172fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulkint IsUnused(struct drive *drive, int secondary, uint32_t index);
173fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulkint IsKernel(struct drive *drive, int secondary, uint32_t index);
174fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulk
1754cb5497984642b8cbd592c14cb1912a787b2d4d7Bill Richardson// Optional. Applications that need this must provide an implementation.
1764cb5497984642b8cbd592c14cb1912a787b2d4d7Bill Richardson//
1774cb5497984642b8cbd592c14cb1912a787b2d4d7Bill Richardson// Explanation:
1784cb5497984642b8cbd592c14cb1912a787b2d4d7Bill Richardson//   Some external utilities need to manipulate the GPT, but don't create new
1794cb5497984642b8cbd592c14cb1912a787b2d4d7Bill Richardson//   partitions from scratch. The cgpt executable uses libuuid to provide this
1804cb5497984642b8cbd592c14cb1912a787b2d4d7Bill Richardson//   functionality, but we don't want to have to build or install a separate
1814cb5497984642b8cbd592c14cb1912a787b2d4d7Bill Richardson//   instance of that library just for the 32-bit static post-install tool,
1824cb5497984642b8cbd592c14cb1912a787b2d4d7Bill Richardson//   which doesn't need this function.
1834cb5497984642b8cbd592c14cb1912a787b2d4d7Bill Richardsonint GenerateGuid(Guid *newguid);
1844cb5497984642b8cbd592c14cb1912a787b2d4d7Bill Richardson
185f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson// For usage and error messages.
186f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonvoid Error(const char *format, ...);
1876ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyenvoid Warning(const char *format, ...);
188f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
189f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson// Command functions.
190f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonint cmd_show(int argc, char *argv[]);
191f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonint cmd_repair(int argc, char *argv[]);
192f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonint cmd_create(int argc, char *argv[]);
193f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonint cmd_add(int argc, char *argv[]);
194f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonint cmd_boot(int argc, char *argv[]);
1954a2093129f226b4b2b4684f2aebe2f4368f85facBill Richardsonint cmd_find(int argc, char *argv[]);
1963430b32667937a75c7a3afc83f8f7a601a8187f7Bill Richardsonint cmd_prioritize(int argc, char *argv[]);
197b7b865cfee68190babd971ab9a897bdabbab075fStefan Reinauerint cmd_legacy(int argc, char *argv[]);
198f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
199f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson#define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0]))
200f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardsonconst char *GptError(int errnum);
201f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
202c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson// Size in chars of the GPT Entry's PartitionName field
203c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson#define GPT_PARTNAME_LEN 72
204c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson
205c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson/* The standard "assert" macro goes away when NDEBUG is defined. This doesn't.
206c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson */
207c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson#define require(A) do { \
208c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson  if (!(A)) { \
209c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson    fprintf(stderr, "condition (%s) failed at %s:%d\n", \
210c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson            #A, __FILE__, __LINE__); \
211c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson    exit(1); } \
212c4e92af85ac2bfd90ab82c0b13bb0041595a0affBill Richardson  } while (0)
213f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson
214f1372d9109d638fbb1a177a89ebaf64e7ee0637eBill Richardson#endif  // VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
215