diff options
Diffstat (limited to 'libinstaller/syslxint.h')
-rw-r--r-- | libinstaller/syslxint.h | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/libinstaller/syslxint.h b/libinstaller/syslxint.h new file mode 100644 index 0000000..7eee789 --- /dev/null +++ b/libinstaller/syslxint.h @@ -0,0 +1,342 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved + * Copyright 2009-2014 Intel Corporation; author: H. Peter Anvin + * Copyright 2011 Paulo Alcantara <pcacjr@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 53 Temple Place Ste 330, + * Boston MA 02111-1307, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#ifndef SYSLXINT_H +#define SYSLXINT_H + +#include "syslinux.h" + +#if defined(__386__) || defined(__i386__) || defined(__x86_64__) +# define X86_MEM 1 /* Littleendian and unaligned safe */ +#else +# define X86_MEM 0 +#endif + +#ifdef __GNUC__ +# ifdef __MINGW32__ + /* gcc 4.7 miscompiles packed structures in MS-bitfield mode */ +# define PACKED __attribute__((packed,gcc_struct)) +# else +# define PACKED __attribute__((packed)) +# endif +#else +# error "Need to define PACKED for this compiler" +#endif + +/* + * Access functions for littleendian numbers, possibly misaligned. + */ +static inline uint8_t get_8(const uint8_t * p) +{ + return *p; +} + +static inline uint16_t get_16(const uint16_t * p) +{ +#if X86_MEM + /* Littleendian and unaligned-capable */ + return *p; +#else + const uint8_t *pp = (const uint8_t *)p; + return pp[0] + ((uint16_t)pp[1] << 8); +#endif +} + +static inline uint32_t get_32(const uint32_t * p) +{ +#if X86_MEM + /* Littleendian and unaligned-capable */ + return *p; +#else + const uint16_t *pp = (const uint16_t *)p; + return get_16(&pp[0]) + ((uint32_t)get_16(&pp[1]) << 16); +#endif +} + +static inline uint64_t get_64(const uint64_t * p) +{ +#if X86_MEM + /* Littleendian and unaligned-capable */ + return *p; +#else + const uint32_t *pp = (const uint32_t *)p; + return get_32(&pp[0]) + ((uint64_t)get_32(&pp[1]) << 32); +#endif +} + +static inline void set_8(uint8_t *p, uint8_t v) +{ + *p = v; +} + +static inline void set_16(uint16_t *p, uint16_t v) +{ +#if X86_MEM + /* Littleendian and unaligned-capable */ + *p = v; +#else + uint8_t *pp = (uint8_t *) p; + pp[0] = v; + pp[1] = v >> 8; +#endif +} + +static inline void set_32(uint32_t *p, uint32_t v) +{ +#if X86_MEM + /* Littleendian and unaligned-capable */ + *p = v; +#else + uint16_t *pp = (uint16_t *) p; + set_16(&pp[0], v); + set_16(&pp[1], v >> 16); +#endif +} + +static inline void set_64(uint64_t *p, uint64_t v) +{ +#if X86_MEM + /* Littleendian and unaligned-capable */ + *p = v; +#else + uint32_t *pp = (uint32_t *) p; + set_32(&pp[0], v); + set_32(&pp[1], v >> 32); +#endif +} + +/* + * Special handling for the MS-DOS derivative: syslinux_ldlinux + * is a "far" object... + */ +#ifdef __MSDOS__ + +uint8_t get_8_sl(const uint8_t _slimg * p); +uint16_t get_16_sl(const uint16_t _slimg * p); +uint32_t get_32_sl(const uint32_t _slimg * p); +uint64_t get_64_sl(const uint64_t _slimg * p); +void set_8_sl(uint8_t _slimg * p, uint8_t v); +void set_16_sl(uint16_t _slimg * p, uint16_t v); +void set_32_sl(uint32_t _slimg * p, uint32_t v); +void set_64_sl(uint64_t _slimg * p, uint64_t v); +void memcpy_to_sl(void _slimg *dst, const void *src, size_t len); +void memcpy_from_sl(void *dst, const void _slimg *src, size_t len); +void memset_sl(void _slimg *dst, int c, size_t len); + +#else + +/* Sane system ... */ +static inline uint8_t get_8_sl(const uint8_t _slimg * p) +{ + return get_8((const uint8_t _force *)p); +} +static inline uint16_t get_16_sl(const uint16_t _slimg * p) +{ + return get_16((const uint16_t _force *)p); +} +static inline uint32_t get_32_sl(const uint32_t _slimg * p) +{ + return get_32((const uint32_t _force *)p); +} +static inline uint64_t get_64_sl(const uint64_t _slimg * p) +{ + return get_64((const uint64_t _force *)p); +} +static inline void set_8_sl(uint8_t _slimg * p, uint8_t v) +{ + set_8((uint8_t _force *)p, v); +} +static inline void set_16_sl(uint16_t _slimg * p, uint16_t v) +{ + set_16((uint16_t _force *)p, v); +} +static inline void set_32_sl(uint32_t _slimg * p, uint32_t v) +{ + set_32((uint32_t _force *)p, v); +} +static inline void set_64_sl(uint64_t _slimg * p, uint64_t v) +{ + set_64((uint64_t _force *)p, v); +} +static inline void memcpy_to_sl(void _slimg *dst, const void *src, size_t len) +{ + memcpy((void _force *)dst, src, len); +} +static inline void memcpy_from_sl(void *dst, const void _slimg *src, size_t len) +{ + memcpy(dst, (const void _force *)src, len); +} +static inline void memset_sl(void _slimg *dst, int c, size_t len) +{ + memset((void _force *)dst, c, len); +} + +#endif + +#define LDLINUX_MAGIC 0x3eb202fe +#define BS_MAGIC_VER (0x1b << 9) + +/* Patch area for disk-based installers */ +struct patch_area { + uint32_t magic; /* LDLINUX_MAGIC */ + uint32_t instance; /* Per-version value */ + uint16_t data_sectors; + uint16_t adv_sectors; + uint32_t dwords; + uint32_t checksum; + uint16_t maxtransfer; + uint16_t epaoffset; /* Pointer to the extended patch area */ +}; + +struct ext_patch_area { + uint16_t advptroffset; /* ADV pointers */ + uint16_t diroffset; /* Current directory field */ + uint16_t dirlen; /* Length of current directory field */ + uint16_t subvoloffset; /* Subvolume field */ + uint16_t subvollen; /* Length of subvolume field */ + uint16_t secptroffset; /* Sector extent pointers */ + uint16_t secptrcnt; /* Number of sector extent pointers */ + + uint16_t sect1ptr0; /* Boot sector offset of sector 1 ptr LSW */ + uint16_t sect1ptr1; /* Boot sector offset of sector 1 ptr MSW */ + uint16_t raidpatch; /* Boot sector RAID mode patch pointer */ +}; + +/* Sector extent */ +struct syslinux_extent { + uint64_t lba; + uint16_t len; +} PACKED; + +/* FAT bootsector format, also used by other disk-based derivatives */ +struct fat_boot_sector { + uint8_t bsJump[3]; + char bsOemName[8]; + uint16_t bsBytesPerSec; + uint8_t bsSecPerClust; + uint16_t bsResSectors; + uint8_t bsFATs; + uint16_t bsRootDirEnts; + uint16_t bsSectors; + uint8_t bsMedia; + uint16_t bsFATsecs; + uint16_t bsSecPerTrack; + uint16_t bsHeads; + uint32_t bsHiddenSecs; + uint32_t bsHugeSectors; + + union { + struct { + uint8_t DriveNumber; + uint8_t Reserved1; + uint8_t BootSignature; + uint32_t VolumeID; + char VolumeLabel[11]; + char FileSysType[8]; + uint8_t Code[442]; + } PACKED bs16; + struct { + uint32_t FATSz32; + uint16_t ExtFlags; + uint16_t FSVer; + uint32_t RootClus; + uint16_t FSInfo; + uint16_t BkBootSec; + uint8_t Reserved0[12]; + uint8_t DriveNumber; + uint8_t Reserved1; + uint8_t BootSignature; + uint32_t VolumeID; + char VolumeLabel[11]; + char FileSysType[8]; + uint8_t Code[414]; + } PACKED bs32; + } PACKED; + + uint32_t bsMagic; + uint16_t bsForwardPtr; + uint16_t bsSignature; +} PACKED; + +/* NTFS bootsector format */ +struct ntfs_boot_sector { + uint8_t bsJump[3]; + char bsOemName[8]; + uint16_t bsBytesPerSec; + uint8_t bsSecPerClust; + uint16_t bsResSectors; + uint8_t bsZeroed_0[3]; + uint16_t bsZeroed_1; + uint8_t bsMedia; + uint16_t bsZeroed_2; + uint16_t bsUnused_0; + uint16_t bsUnused_1; + uint32_t bsUnused_2; + uint32_t bsZeroed_3; + uint32_t bsUnused_3; + uint64_t bsTotalSectors; + uint64_t bsMFTLogicalClustNr; + uint64_t bsMFTMirrLogicalClustNr; + uint8_t bsClustPerMFTrecord; + uint8_t bsUnused_4[3]; + uint8_t bsClustPerIdxBuf; + uint8_t bsUnused_5[3]; + uint64_t bsVolSerialNr; + uint32_t bsUnused_6; + + uint8_t Code[420]; + + uint32_t bsMagic; + uint16_t bsForwardPtr; + uint16_t bsSignature; +} PACKED; + +#define FAT_bsHead bsJump +#define FAT_bsHeadLen offsetof(struct fat_boot_sector, bsBytesPerSec) +#define FAT_bsCode bs32.Code /* The common safe choice */ +#define FAT_bsCodeLen (offsetof(struct fat_boot_sector, bsSignature) - \ + offsetof(struct fat_boot_sector, FAT_bsCode)) + +#define NTFS_bsHead bsJump +#define NTFS_bsHeadLen offsetof(struct ntfs_boot_sector, bsOemName) +#define NTFS_bsCode Code +#define NTFS_bsCodeLen (offsetof(struct ntfs_boot_sector, bsSignature) - \ + offsetof(struct ntfs_boot_sector, NTFS_bsCode)) + +/* Check if there are specific zero fields in an NTFS boot sector */ +static inline int ntfs_check_zero_fields(const struct ntfs_boot_sector *sb) +{ + return !sb->bsResSectors && (!sb->bsZeroed_0[0] && !sb->bsZeroed_0[1] && + !sb->bsZeroed_0[2]) && !sb->bsZeroed_1 && !sb->bsZeroed_2 && + !sb->bsZeroed_3; +} + +static inline int ntfs_check_sb_fields(const struct ntfs_boot_sector *sb) +{ + return ntfs_check_zero_fields(sb) && + (!memcmp(sb->bsOemName, "NTFS ", 8) || + !memcmp(sb->bsOemName, "MSWIN4.0", 8) || + !memcmp(sb->bsOemName, "MSWIN4.1", 8)); +} + +static inline int fat_check_sb_fields(const struct fat_boot_sector *sb) +{ + return sb->bsResSectors && sb->bsFATs && + (!memcmp(sb->bs16.FileSysType, "FAT12 ", 8) || + !memcmp(sb->bs16.FileSysType, "FAT16 ", 8) || + !memcmp(sb->bs16.FileSysType, "FAT ", 8) || + !memcmp(sb->bs32.FileSysType, "FAT32 ", 8)); +} + +#endif /* SYSLXINT_H */ |