|
|
1.1 ! root 1: /* misc.h - prototypes for misc functions */ ! 2: /* ! 3: * GRUB -- GRand Unified Bootloader ! 4: * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. ! 5: * ! 6: * GRUB is free software: you can redistribute it and/or modify ! 7: * it under the terms of the GNU General Public License as published by ! 8: * the Free Software Foundation, either version 3 of the License, or ! 9: * (at your option) any later version. ! 10: * ! 11: * GRUB is distributed in the hope that it will be useful, ! 12: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: * GNU General Public License for more details. ! 15: * ! 16: * You should have received a copy of the GNU General Public License ! 17: * along with GRUB. If not, see <http://www.gnu.org/licenses/>. ! 18: */ ! 19: ! 20: #ifndef GRUB_MISC_HEADER ! 21: #define GRUB_MISC_HEADER 1 ! 22: ! 23: #include <stdarg.h> ! 24: #include <grub/types.h> ! 25: #include <grub/symbol.h> ! 26: #include <grub/err.h> ! 27: #include <grub/i18n.h> ! 28: #include <grub/compiler.h> ! 29: ! 30: #define ALIGN_UP(addr, align) \ ! 31: ((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1)) ! 32: #define ALIGN_UP_OVERHEAD(addr, align) ((-(addr)) & ((typeof (addr)) (align) - 1)) ! 33: #define ALIGN_DOWN(addr, align) \ ! 34: ((addr) & ~((typeof (addr)) align - 1)) ! 35: #define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) ! 36: #define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; } ! 37: ! 38: #define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__) ! 39: ! 40: void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n); ! 41: char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src); ! 42: ! 43: static inline char * ! 44: grub_strncpy (char *dest, const char *src, int c) ! 45: { ! 46: char *p = dest; ! 47: ! 48: while ((*p++ = *src++) != '\0' && --c) ! 49: ; ! 50: ! 51: return dest; ! 52: } ! 53: ! 54: static inline char * ! 55: grub_stpcpy (char *dest, const char *src) ! 56: { ! 57: char *d = dest; ! 58: const char *s = src; ! 59: ! 60: do ! 61: *d++ = *s; ! 62: while (*s++ != '\0'); ! 63: ! 64: return d - 1; ! 65: } ! 66: ! 67: /* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ ! 68: static inline void * ! 69: grub_memcpy (void *dest, const void *src, grub_size_t n) ! 70: { ! 71: return grub_memmove (dest, src, n); ! 72: } ! 73: ! 74: #if defined (__APPLE__) && defined(__i386__) && !defined (GRUB_UTIL) ! 75: #define GRUB_BUILTIN_ATTR __attribute__ ((regparm(0))) ! 76: #else ! 77: #define GRUB_BUILTIN_ATTR ! 78: #endif ! 79: ! 80: #if defined(__x86_64__) && !defined (GRUB_UTIL) ! 81: #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (__MINGW64__) ! 82: #define GRUB_ASM_ATTR __attribute__ ((sysv_abi)) ! 83: #else ! 84: #define GRUB_ASM_ATTR ! 85: #endif ! 86: #endif ! 87: ! 88: /* Prototypes for aliases. */ ! 89: #ifndef GRUB_UTIL ! 90: int GRUB_BUILTIN_ATTR EXPORT_FUNC(memcmp) (const void *s1, const void *s2, grub_size_t n); ! 91: void *GRUB_BUILTIN_ATTR EXPORT_FUNC(memmove) (void *dest, const void *src, grub_size_t n); ! 92: void *GRUB_BUILTIN_ATTR EXPORT_FUNC(memcpy) (void *dest, const void *src, grub_size_t n); ! 93: void *GRUB_BUILTIN_ATTR EXPORT_FUNC(memset) (void *s, int c, grub_size_t n); ! 94: ! 95: #ifdef __APPLE__ ! 96: void GRUB_BUILTIN_ATTR EXPORT_FUNC (__bzero) (void *s, grub_size_t n); ! 97: #endif ! 98: ! 99: #endif ! 100: ! 101: int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n); ! 102: int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2); ! 103: int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n); ! 104: ! 105: char *EXPORT_FUNC(grub_strchr) (const char *s, int c); ! 106: char *EXPORT_FUNC(grub_strrchr) (const char *s, int c); ! 107: int EXPORT_FUNC(grub_strword) (const char *s, const char *w); ! 108: ! 109: /* Copied from gnulib. ! 110: Written by Bruno Haible <[email protected]>, 2005. */ ! 111: static inline char * ! 112: grub_strstr (const char *haystack, const char *needle) ! 113: { ! 114: /* Be careful not to look at the entire extent of haystack or needle ! 115: until needed. This is useful because of these two cases: ! 116: - haystack may be very long, and a match of needle found early, ! 117: - needle may be very long, and not even a short initial segment of ! 118: needle may be found in haystack. */ ! 119: if (*needle != '\0') ! 120: { ! 121: /* Speed up the following searches of needle by caching its first ! 122: character. */ ! 123: char b = *needle++; ! 124: ! 125: for (;; haystack++) ! 126: { ! 127: if (*haystack == '\0') ! 128: /* No match. */ ! 129: return 0; ! 130: if (*haystack == b) ! 131: /* The first character matches. */ ! 132: { ! 133: const char *rhaystack = haystack + 1; ! 134: const char *rneedle = needle; ! 135: ! 136: for (;; rhaystack++, rneedle++) ! 137: { ! 138: if (*rneedle == '\0') ! 139: /* Found a match. */ ! 140: return (char *) haystack; ! 141: if (*rhaystack == '\0') ! 142: /* No match. */ ! 143: return 0; ! 144: if (*rhaystack != *rneedle) ! 145: /* Nothing in this round. */ ! 146: break; ! 147: } ! 148: } ! 149: } ! 150: } ! 151: else ! 152: return (char *) haystack; ! 153: } ! 154: ! 155: int EXPORT_FUNC(grub_isspace) (int c); ! 156: ! 157: static inline int ! 158: grub_isprint (int c) ! 159: { ! 160: return (c >= ' ' && c <= '~'); ! 161: } ! 162: ! 163: static inline int ! 164: grub_iscntrl (int c) ! 165: { ! 166: return (c >= 0x00 && c <= 0x1F) || c == 0x7F; ! 167: } ! 168: ! 169: static inline int ! 170: grub_isalpha (int c) ! 171: { ! 172: return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); ! 173: } ! 174: ! 175: static inline int ! 176: grub_islower (int c) ! 177: { ! 178: return (c >= 'a' && c <= 'z'); ! 179: } ! 180: ! 181: static inline int ! 182: grub_isupper (int c) ! 183: { ! 184: return (c >= 'A' && c <= 'Z'); ! 185: } ! 186: ! 187: static inline int ! 188: grub_isgraph (int c) ! 189: { ! 190: return (c >= '!' && c <= '~'); ! 191: } ! 192: ! 193: static inline int ! 194: grub_isdigit (int c) ! 195: { ! 196: return (c >= '0' && c <= '9'); ! 197: } ! 198: ! 199: static inline int ! 200: grub_isxdigit (int c) ! 201: { ! 202: return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); ! 203: } ! 204: ! 205: static inline int ! 206: grub_isalnum (int c) ! 207: { ! 208: return grub_isalpha (c) || grub_isdigit (c); ! 209: } ! 210: ! 211: static inline int ! 212: grub_tolower (int c) ! 213: { ! 214: if (c >= 'A' && c <= 'Z') ! 215: return c - 'A' + 'a'; ! 216: ! 217: return c; ! 218: } ! 219: ! 220: static inline int ! 221: grub_toupper (int c) ! 222: { ! 223: if (c >= 'a' && c <= 'z') ! 224: return c - 'a' + 'A'; ! 225: ! 226: return c; ! 227: } ! 228: ! 229: static inline int ! 230: grub_strcasecmp (const char *s1, const char *s2) ! 231: { ! 232: while (*s1 && *s2) ! 233: { ! 234: if (grub_tolower ((grub_uint8_t) *s1) ! 235: != grub_tolower ((grub_uint8_t) *s2)) ! 236: break; ! 237: ! 238: s1++; ! 239: s2++; ! 240: } ! 241: ! 242: return (int) grub_tolower ((grub_uint8_t) *s1) ! 243: - (int) grub_tolower ((grub_uint8_t) *s2); ! 244: } ! 245: ! 246: static inline int ! 247: grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) ! 248: { ! 249: if (n == 0) ! 250: return 0; ! 251: ! 252: while (*s1 && *s2 && --n) ! 253: { ! 254: if (grub_tolower (*s1) != grub_tolower (*s2)) ! 255: break; ! 256: ! 257: s1++; ! 258: s2++; ! 259: } ! 260: ! 261: return (int) grub_tolower ((grub_uint8_t) *s1) ! 262: - (int) grub_tolower ((grub_uint8_t) *s2); ! 263: } ! 264: ! 265: unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base); ! 266: unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base); ! 267: ! 268: static inline long ! 269: grub_strtol (const char *str, char **end, int base) ! 270: { ! 271: int negative = 0; ! 272: unsigned long long magnitude; ! 273: ! 274: while (*str && grub_isspace (*str)) ! 275: str++; ! 276: ! 277: if (*str == '-') ! 278: { ! 279: negative = 1; ! 280: str++; ! 281: } ! 282: ! 283: magnitude = grub_strtoull (str, end, base); ! 284: if (negative) ! 285: { ! 286: if (magnitude > (unsigned long) GRUB_LONG_MAX + 1) ! 287: { ! 288: grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ! 289: return GRUB_LONG_MIN; ! 290: } ! 291: return -((long) magnitude); ! 292: } ! 293: else ! 294: { ! 295: if (magnitude > GRUB_LONG_MAX) ! 296: { ! 297: grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ! 298: return GRUB_LONG_MAX; ! 299: } ! 300: return (long) magnitude; ! 301: } ! 302: } ! 303: ! 304: char *EXPORT_FUNC(grub_strdup) (const char *s) WARN_UNUSED_RESULT; ! 305: char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n) WARN_UNUSED_RESULT; ! 306: void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n); ! 307: grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) WARN_UNUSED_RESULT; ! 308: int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); ! 309: int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); ! 310: ! 311: /* Replace all `ch' characters of `input' with `with' and copy the ! 312: result into `output'; return EOS address of `output'. */ ! 313: static inline char * ! 314: grub_strchrsub (char *output, const char *input, char ch, const char *with) ! 315: { ! 316: while (*input) ! 317: { ! 318: if (*input == ch) ! 319: { ! 320: grub_strcpy (output, with); ! 321: output += grub_strlen (with); ! 322: input++; ! 323: continue; ! 324: } ! 325: *output++ = *input++; ! 326: } ! 327: *output = '\0'; ! 328: return output; ! 329: } ! 330: ! 331: extern void (*EXPORT_VAR (grub_xputs)) (const char *str); ! 332: ! 333: static inline int ! 334: grub_puts (const char *s) ! 335: { ! 336: const char nl[2] = "\n"; ! 337: grub_xputs (s); ! 338: grub_xputs (nl); ! 339: ! 340: return 1; /* Cannot fail. */ ! 341: } ! 342: ! 343: int EXPORT_FUNC(grub_puts_) (const char *s); ! 344: void EXPORT_FUNC(grub_real_dprintf) (const char *file, ! 345: const int line, ! 346: const char *condition, ! 347: const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 4, 5))); ! 348: int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args); ! 349: int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...) ! 350: __attribute__ ((format (GNU_PRINTF, 3, 4))); ! 351: int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt, ! 352: va_list args); ! 353: char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...) ! 354: __attribute__ ((format (GNU_PRINTF, 1, 2))) WARN_UNUSED_RESULT; ! 355: char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) WARN_UNUSED_RESULT; ! 356: void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); ! 357: grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, ! 358: grub_uint64_t d, ! 359: grub_uint64_t *r); ! 360: ! 361: #if (defined (__MINGW32__) || defined (__CYGWIN__)) && !defined(GRUB_UTIL) ! 362: void EXPORT_FUNC (__register_frame_info) (void); ! 363: void EXPORT_FUNC (__deregister_frame_info) (void); ! 364: void EXPORT_FUNC (___chkstk_ms) (void); ! 365: void EXPORT_FUNC (__chkstk_ms) (void); ! 366: #endif ! 367: ! 368: /* Inline functions. */ ! 369: ! 370: static inline char * ! 371: grub_memchr (const void *p, int c, grub_size_t len) ! 372: { ! 373: const char *s = (const char *) p; ! 374: const char *e = s + len; ! 375: ! 376: for (; s < e; s++) ! 377: if (*s == c) ! 378: return (char *) s; ! 379: ! 380: return 0; ! 381: } ! 382: ! 383: ! 384: static inline unsigned int ! 385: grub_abs (int x) ! 386: { ! 387: if (x < 0) ! 388: return (unsigned int) (-x); ! 389: else ! 390: return (unsigned int) x; ! 391: } ! 392: ! 393: /* Rounded-up division */ ! 394: static inline unsigned int ! 395: grub_div_roundup (unsigned int x, unsigned int y) ! 396: { ! 397: return (x + y - 1) / y; ! 398: } ! 399: ! 400: /* Reboot the machine. */ ! 401: #if defined (GRUB_MACHINE_EMU) || defined (GRUB_MACHINE_QEMU_MIPS) ! 402: void EXPORT_FUNC(grub_reboot) (void) __attribute__ ((noreturn)); ! 403: #else ! 404: void grub_reboot (void) __attribute__ ((noreturn)); ! 405: #endif ! 406: ! 407: #if defined (__clang__) && !defined (GRUB_UTIL) ! 408: void __attribute__ ((noreturn)) EXPORT_FUNC (abort) (void); ! 409: #endif ! 410: ! 411: #ifdef GRUB_MACHINE_PCBIOS ! 412: /* Halt the system, using APM if possible. If NO_APM is true, don't ! 413: * use APM even if it is available. */ ! 414: void grub_halt (int no_apm) __attribute__ ((noreturn)); ! 415: #elif defined (__mips__) && !defined (GRUB_MACHINE_EMU) ! 416: void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); ! 417: #else ! 418: void grub_halt (void) __attribute__ ((noreturn)); ! 419: #endif ! 420: ! 421: #ifdef GRUB_MACHINE_EMU ! 422: /* Flag to check if module loading is available. */ ! 423: extern const int EXPORT_VAR(grub_no_modules); ! 424: #else ! 425: #define grub_no_modules 0 ! 426: #endif ! 427: ! 428: static inline void ! 429: grub_error_save (struct grub_error_saved *save) ! 430: { ! 431: grub_memcpy (save->errmsg, grub_errmsg, sizeof (save->errmsg)); ! 432: save->grub_errno = grub_errno; ! 433: grub_errno = GRUB_ERR_NONE; ! 434: } ! 435: ! 436: static inline void ! 437: grub_error_load (const struct grub_error_saved *save) ! 438: { ! 439: grub_memcpy (grub_errmsg, save->errmsg, sizeof (grub_errmsg)); ! 440: grub_errno = save->grub_errno; ! 441: } ! 442: ! 443: #ifndef GRUB_UTIL ! 444: ! 445: #if defined (__arm__) ! 446: ! 447: grub_uint32_t ! 448: EXPORT_FUNC (__udivsi3) (grub_uint32_t a, grub_uint32_t b); ! 449: ! 450: grub_uint32_t ! 451: EXPORT_FUNC (__umodsi3) (grub_uint32_t a, grub_uint32_t b); ! 452: ! 453: #endif ! 454: ! 455: #if defined (__sparc__) || defined (__powerpc__) ! 456: unsigned ! 457: EXPORT_FUNC (__ctzdi2) (grub_uint64_t x); ! 458: #define NEED_CTZDI2 1 ! 459: #endif ! 460: ! 461: #if defined (__mips__) || defined (__arm__) ! 462: unsigned ! 463: EXPORT_FUNC (__ctzsi2) (grub_uint32_t x); ! 464: #define NEED_CTZSI2 1 ! 465: #endif ! 466: ! 467: #ifdef __arm__ ! 468: grub_uint32_t ! 469: EXPORT_FUNC (__aeabi_uidiv) (grub_uint32_t a, grub_uint32_t b); ! 470: grub_uint32_t ! 471: EXPORT_FUNC (__aeabi_uidivmod) (grub_uint32_t a, grub_uint32_t b); ! 472: ! 473: /* Needed for allowing modules to be compiled as thumb. */ ! 474: grub_uint64_t ! 475: EXPORT_FUNC (__muldi3) (grub_uint64_t a, grub_uint64_t b); ! 476: grub_uint64_t ! 477: EXPORT_FUNC (__aeabi_lmul) (grub_uint64_t a, grub_uint64_t b); ! 478: ! 479: #endif ! 480: ! 481: #if defined (__ia64__) ! 482: ! 483: grub_uint64_t ! 484: EXPORT_FUNC (__udivdi3) (grub_uint64_t a, grub_uint64_t b); ! 485: ! 486: grub_uint64_t ! 487: EXPORT_FUNC (__umoddi3) (grub_uint64_t a, grub_uint64_t b); ! 488: ! 489: #endif ! 490: ! 491: #endif /* GRUB_UTIL */ ! 492: ! 493: ! 494: #if BOOT_TIME_STATS ! 495: struct grub_boot_time ! 496: { ! 497: struct grub_boot_time *next; ! 498: grub_uint64_t tp; ! 499: const char *file; ! 500: int line; ! 501: char *msg; ! 502: }; ! 503: ! 504: extern struct grub_boot_time *EXPORT_VAR(grub_boot_time_head); ! 505: ! 506: void EXPORT_FUNC(grub_real_boot_time) (const char *file, ! 507: const int line, ! 508: const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 3, 4))); ! 509: #define grub_boot_time(...) grub_real_boot_time(GRUB_FILE, __LINE__, __VA_ARGS__) ! 510: #else ! 511: #define grub_boot_time(...) ! 512: #endif ! 513: ! 514: #define grub_max(a, b) (((a) > (b)) ? (a) : (b)) ! 515: #define grub_min(a, b) (((a) < (b)) ? (a) : (b)) ! 516: ! 517: #endif /* ! GRUB_MISC_HEADER */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.