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