win: Add -mno-ms-bitfields
[profile/ivi/syslinux.git] / libinstaller / syslxint.h
1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
4  *   Copyright 2009-2011 Intel Corporation; author: H. Peter Anvin
5  *   Copyright 2011 Paulo Alcantara <pcacjr@gmail.com>
6  *
7  *   This program is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU General Public License as published by
9  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
10  *   Boston MA 02111-1307, USA; either version 2 of the License, or
11  *   (at your option) any later version; incorporated herein by reference.
12  *
13  * ----------------------------------------------------------------------- */
14
15 #ifndef SYSLXINT_H
16 #define SYSLXINT_H
17
18 #include "syslinux.h"
19
20 #if defined(__386__) || defined(__i386__) || defined(__x86_64__)
21 # define X86_MEM 1              /* Littleendian and unaligned safe */
22 #else
23 # define X86_MEM 0
24 #endif
25
26 /*
27  * Access functions for littleendian numbers, possibly misaligned.
28  */
29 static inline uint8_t get_8(const uint8_t * p)
30 {
31     return *p;
32 }
33
34 static inline uint16_t get_16(const uint16_t * p)
35 {
36 #if X86_MEM
37     /* Littleendian and unaligned-capable */
38     return *p;
39 #else
40     const uint8_t *pp = (const uint8_t *)p;
41     return pp[0] + ((uint16_t)pp[1] << 8);
42 #endif
43 }
44
45 static inline uint32_t get_32(const uint32_t * p)
46 {
47 #if X86_MEM
48     /* Littleendian and unaligned-capable */
49     return *p;
50 #else
51     const uint16_t *pp = (const uint16_t *)p;
52     return get_16(pp[0]) + (uint32_t)get_16(pp[1]);
53 #endif
54 }
55
56 static inline uint64_t get_64(const uint64_t * p)
57 {
58 #if X86_MEM
59     /* Littleendian and unaligned-capable */
60     return *p;
61 #else
62     const uint32_t *pp = (const uint32_t *)p;
63     return get_32(pp[0]) + (uint64_t)get_32(pp[1]);
64 #endif
65 }
66
67 static inline void set_8(uint8_t *p, uint8_t v)
68 {
69     *p = v;
70 }
71
72 static inline void set_16(uint16_t *p, uint16_t v)
73 {
74 #if X86_MEM
75     /* Littleendian and unaligned-capable */
76     *p = v;
77 #else
78     uint8_t *pp = (uint8_t *) p;
79     pp[0] = (v & 0xff);
80     pp[1] = ((v >> 8) & 0xff);
81 #endif
82 }
83
84 static inline void set_32(uint32_t *p, uint32_t v)
85 {
86 #if X86_MEM
87     /* Littleendian and unaligned-capable */
88     *p = v;
89 #else
90     uint8_t *pp = (uint8_t *) p;
91     pp[0] = (v & 0xff);
92     pp[1] = ((v >> 8) & 0xff);
93     pp[2] = ((v >> 16) & 0xff);
94     pp[3] = ((v >> 24) & 0xff);
95 #endif
96 }
97
98 static inline void set_64(uint64_t *p, uint64_t v)
99 {
100 #if X86_MEM
101     /* Littleendian and unaligned-capable */
102     *p = v;
103 #else
104     uint32_t *pp = (uint32_t *) p;
105     set_32(pp[0], v);
106     set_32(pp[1], v >> 32);
107 #endif
108 }
109
110 /*
111  * Special handling for the MS-DOS derivative: syslinux_ldlinux
112  * is a "far" object...
113  */
114 #ifdef __MSDOS__
115
116 static inline __attribute__ ((const))
117 uint16_t ds(void)
118 {
119     uint16_t v;
120     asm("movw %%ds,%0":"=rm"(v));
121     return v;
122 }
123
124 static inline void *set_fs(const void *p)
125 {
126     uint16_t seg;
127
128     seg = ds() + ((size_t) p >> 4);
129     asm volatile ("movw %0,%%fs"::"rm" (seg));
130     return (void *)((size_t) p & 0xf);
131 }
132
133 uint8_t get_8_sl(const uint8_t * p);
134 uint16_t get_16_sl(const uint16_t * p);
135 uint32_t get_32_sl(const uint32_t * p);
136 uint64_t get_64_sl(const uint64_t * p);
137 void set_8_sl(uint8_t * p, uint8_t v);
138 void set_16_sl(uint16_t * p, uint16_t v);
139 void set_32_sl(uint32_t * p, uint32_t v);
140 void set_64_sl(uint64_t * p, uint64_t v);
141 void memcpy_to_sl(void *dst, const void *src, size_t len);
142 void memcpy_from_sl(void *dst, const void *src, size_t len);
143
144 #else
145
146 /* Sane system ... */
147 #define get_8_sl(x)             get_8(x)
148 #define get_16_sl(x)            get_16(x)
149 #define get_32_sl(x)            get_32(x)
150 #define get_64_sl(x)            get_64(x)
151 #define set_8_sl(x,y)           set_8(x,y)
152 #define set_16_sl(x,y)          set_16(x,y)
153 #define set_32_sl(x,y)          set_32(x,y)
154 #define set_64_sl(x,y)          set_64(x,y)
155 #define memcpy_to_sl(d,s,l)     memcpy(d,s,l)
156 #define memcpy_from_sl(d,s,l)   memcpy(d,s,l)
157
158 #endif
159
160 #define LDLINUX_MAGIC   0x3eb202fe
161 #define BS_MAGIC_VER    (0x1b << 9)
162
163 /* Patch area for disk-based installers */
164 struct patch_area {
165     uint32_t magic;             /* LDLINUX_MAGIC */
166     uint32_t instance;          /* Per-version value */
167     uint16_t data_sectors;
168     uint16_t adv_sectors;
169     uint32_t dwords;
170     uint32_t checksum;
171     uint16_t maxtransfer;
172     uint16_t epaoffset;         /* Pointer to the extended patch area */
173 };
174
175 struct ext_patch_area {
176     uint16_t advptroffset;      /* ADV pointers */
177     uint16_t diroffset;         /* Current directory field */
178     uint16_t dirlen;            /* Length of current directory field */
179     uint16_t subvoloffset;      /* Subvolume field */
180     uint16_t subvollen;         /* Length of subvolume field */
181     uint16_t secptroffset;      /* Sector extent pointers */
182     uint16_t secptrcnt;         /* Number of sector extent pointers */
183
184     uint16_t sect1ptr0;         /* Boot sector offset of sector 1 ptr LSW */
185     uint16_t sect1ptr1;         /* Boot sector offset of sector 1 ptr MSW */
186     uint16_t raidpatch;         /* Boot sector RAID mode patch pointer */
187 };
188
189 /* Sector extent */
190 struct syslinux_extent {
191     uint64_t lba;
192     uint16_t len;
193 } __attribute__((packed));
194
195 /* FAT bootsector format, also used by other disk-based derivatives */
196 struct fat_boot_sector {
197     uint8_t bsJump[3];
198     char bsOemName[8];
199     uint16_t bsBytesPerSec;
200     uint8_t bsSecPerClust;
201     uint16_t bsResSectors;
202     uint8_t bsFATs;
203     uint16_t bsRootDirEnts;
204     uint16_t bsSectors;
205     uint8_t bsMedia;
206     uint16_t bsFATsecs;
207     uint16_t bsSecPerTrack;
208     uint16_t bsHeads;
209     uint32_t bsHiddenSecs;
210     uint32_t bsHugeSectors;
211
212     union {
213         struct {
214             uint8_t DriveNumber;
215             uint8_t Reserved1;
216             uint8_t BootSignature;
217             uint32_t VolumeID;
218             char VolumeLabel[11];
219             char FileSysType[8];
220             uint8_t Code[442];
221         } __attribute__ ((packed)) bs16;
222         struct {
223             uint32_t FATSz32;
224             uint16_t ExtFlags;
225             uint16_t FSVer;
226             uint32_t RootClus;
227             uint16_t FSInfo;
228             uint16_t BkBootSec;
229             uint8_t Reserved0[12];
230             uint8_t DriveNumber;
231             uint8_t Reserved1;
232             uint8_t BootSignature;
233             uint32_t VolumeID;
234             char VolumeLabel[11];
235             char FileSysType[8];
236             uint8_t Code[414];
237         } __attribute__ ((packed)) bs32;
238     } __attribute__ ((packed));
239
240     uint32_t bsMagic;
241     uint16_t bsForwardPtr;
242     uint16_t bsSignature;
243 } __attribute__ ((packed));
244
245 /* NTFS bootsector format */
246 struct ntfs_boot_sector {
247     uint8_t bsJump[3];
248     char bsOemName[8];
249     uint16_t bsBytesPerSec;
250     uint8_t bsSecPerClust;
251     uint16_t bsResSectors;
252     uint8_t bsZeroed_0[3];
253     uint16_t bsZeroed_1;
254     uint8_t bsMedia;
255     uint16_t bsZeroed_2;
256     uint16_t bsUnused_0;
257     uint16_t bsUnused_1;
258     uint32_t bsUnused_2;
259     uint32_t bsZeroed_3;
260     uint32_t bsUnused_3;
261     uint64_t bsTotalSectors;
262     uint64_t bsMFTLogicalClustNr;
263     uint64_t bsMFTMirrLogicalClustNr;
264     uint8_t bsClustPerMFTrecord;
265     uint8_t bsUnused_4[3];
266     uint8_t bsClustPerIdxBuf;
267     uint8_t bsUnused_5[3];
268     uint64_t bsVolSerialNr;
269     uint32_t bsUnused_6;
270
271     uint8_t Code[420];
272
273     uint32_t bsMagic;
274     uint16_t bsForwardPtr;
275     uint16_t bsSignature;
276 } __attribute__((packed));
277
278 #define FAT_bsHead      bsJump
279 #define FAT_bsHeadLen   offsetof(struct fat_boot_sector, bsBytesPerSec)
280 #define FAT_bsCode          bs32.Code   /* The common safe choice */
281 #define FAT_bsCodeLen   (offsetof(struct fat_boot_sector, bsSignature) - \
282                      offsetof(struct fat_boot_sector, FAT_bsCode))
283
284 #define NTFS_bsHead     bsJump
285 #define NTFS_bsHeadLen  offsetof(struct ntfs_boot_sector, bsOemName)
286 #define NTFS_bsCode     Code
287 #define NTFS_bsCodeLen  (offsetof(struct ntfs_boot_sector, bsSignature) - \
288                             offsetof(struct ntfs_boot_sector, NTFS_bsCode))
289
290 /* Check if there are specific zero fields in an NTFS boot sector */
291 static inline int ntfs_check_zero_fields(const struct ntfs_boot_sector *sb)
292 {
293     return !sb->bsResSectors && (!sb->bsZeroed_0[0] && !sb->bsZeroed_0[1] &&
294             !sb->bsZeroed_0[2]) && !sb->bsZeroed_1 && !sb->bsZeroed_2 &&
295             !sb->bsZeroed_3;
296 }
297
298 static inline int ntfs_check_sb_fields(const struct ntfs_boot_sector *sb)
299 {
300     return ntfs_check_zero_fields(sb) &&
301             (!memcmp(sb->bsOemName, "NTFS    ", 8) ||
302              !memcmp(sb->bsOemName, "MSWIN4.0", 8) ||
303              !memcmp(sb->bsOemName, "MSWIN4.1", 8));
304 }
305
306 static inline int fat_check_sb_fields(const struct fat_boot_sector *sb)
307 {
308     return sb->bsResSectors && sb->bsFATs &&
309             (!memcmp(sb->bs16.FileSysType, "FAT12   ", 8) ||
310              !memcmp(sb->bs16.FileSysType, "FAT16   ", 8) ||
311              !memcmp(sb->bs16.FileSysType, "FAT     ", 8) ||
312              !memcmp(sb->bs32.FileSysType, "FAT32   ", 8));
313 }
314
315 #endif /* SYSLXINT_H */