• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
4  *   Copyright 2009-2014 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 #ifdef __GNUC__
27 # ifdef __MINGW32__
28    /* gcc 4.7 miscompiles packed structures in MS-bitfield mode */
29 #  define PACKED __attribute__((packed,gcc_struct))
30 # else
31 #  define PACKED __attribute__((packed))
32 # endif
33 #else
34 # error "Need to define PACKED for this compiler"
35 #endif
36 
37 /*
38  * Access functions for littleendian numbers, possibly misaligned.
39  */
get_8(const uint8_t * p)40 static inline uint8_t get_8(const uint8_t * p)
41 {
42     return *p;
43 }
44 
get_16(const uint16_t * p)45 static inline uint16_t get_16(const uint16_t * p)
46 {
47 #if X86_MEM
48     /* Littleendian and unaligned-capable */
49     return *p;
50 #else
51     const uint8_t *pp = (const uint8_t *)p;
52     return pp[0] + ((uint16_t)pp[1] << 8);
53 #endif
54 }
55 
get_32(const uint32_t * p)56 static inline uint32_t get_32(const uint32_t * p)
57 {
58 #if X86_MEM
59     /* Littleendian and unaligned-capable */
60     return *p;
61 #else
62     const uint16_t *pp = (const uint16_t *)p;
63     return get_16(&pp[0]) + ((uint32_t)get_16(&pp[1]) << 16);
64 #endif
65 }
66 
get_64(const uint64_t * p)67 static inline uint64_t get_64(const uint64_t * p)
68 {
69 #if X86_MEM
70     /* Littleendian and unaligned-capable */
71     return *p;
72 #else
73     const uint32_t *pp = (const uint32_t *)p;
74     return get_32(&pp[0]) + ((uint64_t)get_32(&pp[1]) << 32);
75 #endif
76 }
77 
set_8(uint8_t * p,uint8_t v)78 static inline void set_8(uint8_t *p, uint8_t v)
79 {
80     *p = v;
81 }
82 
set_16(uint16_t * p,uint16_t v)83 static inline void set_16(uint16_t *p, uint16_t v)
84 {
85 #if X86_MEM
86     /* Littleendian and unaligned-capable */
87     *p = v;
88 #else
89     uint8_t *pp = (uint8_t *) p;
90     pp[0] = v;
91     pp[1] = v >> 8;
92 #endif
93 }
94 
set_32(uint32_t * p,uint32_t v)95 static inline void set_32(uint32_t *p, uint32_t v)
96 {
97 #if X86_MEM
98     /* Littleendian and unaligned-capable */
99     *p = v;
100 #else
101     uint16_t *pp = (uint16_t *) p;
102     set_16(&pp[0], v);
103     set_16(&pp[1], v >> 16);
104 #endif
105 }
106 
set_64(uint64_t * p,uint64_t v)107 static inline void set_64(uint64_t *p, uint64_t v)
108 {
109 #if X86_MEM
110     /* Littleendian and unaligned-capable */
111     *p = v;
112 #else
113     uint32_t *pp = (uint32_t *) p;
114     set_32(&pp[0], v);
115     set_32(&pp[1], v >> 32);
116 #endif
117 }
118 
119 /*
120  * Special handling for the MS-DOS derivative: syslinux_ldlinux
121  * is a "far" object...
122  */
123 #ifdef __MSDOS__
124 
125 uint8_t get_8_sl(const uint8_t _slimg * p);
126 uint16_t get_16_sl(const uint16_t _slimg * p);
127 uint32_t get_32_sl(const uint32_t _slimg * p);
128 uint64_t get_64_sl(const uint64_t _slimg * p);
129 void set_8_sl(uint8_t _slimg * p, uint8_t v);
130 void set_16_sl(uint16_t _slimg * p, uint16_t v);
131 void set_32_sl(uint32_t _slimg * p, uint32_t v);
132 void set_64_sl(uint64_t _slimg * p, uint64_t v);
133 void memcpy_to_sl(void _slimg *dst, const void *src, size_t len);
134 void memcpy_from_sl(void *dst, const void _slimg *src, size_t len);
135 void memset_sl(void _slimg *dst, int c, size_t len);
136 
137 #else
138 
139 /* Sane system ... */
get_8_sl(const uint8_t _slimg * p)140 static inline uint8_t get_8_sl(const uint8_t _slimg * p)
141 {
142     return get_8((const uint8_t _force *)p);
143 }
get_16_sl(const uint16_t _slimg * p)144 static inline uint16_t get_16_sl(const uint16_t _slimg * p)
145 {
146     return get_16((const uint16_t _force *)p);
147 }
get_32_sl(const uint32_t _slimg * p)148 static inline uint32_t get_32_sl(const uint32_t _slimg * p)
149 {
150     return get_32((const uint32_t _force *)p);
151 }
get_64_sl(const uint64_t _slimg * p)152 static inline uint64_t get_64_sl(const uint64_t _slimg * p)
153 {
154     return get_64((const uint64_t _force *)p);
155 }
set_8_sl(uint8_t _slimg * p,uint8_t v)156 static inline void set_8_sl(uint8_t _slimg * p, uint8_t v)
157 {
158     set_8((uint8_t _force *)p, v);
159 }
set_16_sl(uint16_t _slimg * p,uint16_t v)160 static inline void set_16_sl(uint16_t _slimg * p, uint16_t v)
161 {
162     set_16((uint16_t _force *)p, v);
163 }
set_32_sl(uint32_t _slimg * p,uint32_t v)164 static inline void set_32_sl(uint32_t _slimg * p, uint32_t v)
165 {
166     set_32((uint32_t _force *)p, v);
167 }
set_64_sl(uint64_t _slimg * p,uint64_t v)168 static inline void set_64_sl(uint64_t _slimg * p, uint64_t v)
169 {
170     set_64((uint64_t _force *)p, v);
171 }
memcpy_to_sl(void _slimg * dst,const void * src,size_t len)172 static inline void memcpy_to_sl(void _slimg *dst, const void *src, size_t len)
173 {
174     memcpy((void _force *)dst, src, len);
175 }
memcpy_from_sl(void * dst,const void _slimg * src,size_t len)176 static inline void memcpy_from_sl(void *dst, const void _slimg *src, size_t len)
177 {
178     memcpy(dst, (const void _force *)src, len);
179 }
memset_sl(void _slimg * dst,int c,size_t len)180 static inline void memset_sl(void _slimg *dst, int c, size_t len)
181 {
182     memset((void _force *)dst, c, len);
183 }
184 
185 #endif
186 
187 #define LDLINUX_MAGIC	0x3eb202fe
188 #define BS_MAGIC_VER	(0x1b << 9)
189 
190 /* Patch area for disk-based installers */
191 struct patch_area {
192     uint32_t magic;		/* LDLINUX_MAGIC */
193     uint32_t instance;		/* Per-version value */
194     uint16_t data_sectors;
195     uint16_t adv_sectors;
196     uint32_t dwords;
197     uint32_t checksum;
198     uint16_t maxtransfer;
199     uint16_t epaoffset;		/* Pointer to the extended patch area */
200 };
201 
202 struct ext_patch_area {
203     uint16_t advptroffset;	/* ADV pointers */
204     uint16_t diroffset;		/* Current directory field */
205     uint16_t dirlen;		/* Length of current directory field */
206     uint16_t subvoloffset;	/* Subvolume field */
207     uint16_t subvollen;		/* Length of subvolume field */
208     uint16_t secptroffset;	/* Sector extent pointers */
209     uint16_t secptrcnt;		/* Number of sector extent pointers */
210 
211     uint16_t sect1ptr0;		/* Boot sector offset of sector 1 ptr LSW */
212     uint16_t sect1ptr1;		/* Boot sector offset of sector 1 ptr MSW */
213     uint16_t raidpatch;		/* Boot sector RAID mode patch pointer */
214 };
215 
216 /* Sector extent */
217 struct syslinux_extent {
218     uint64_t lba;
219     uint16_t len;
220 } PACKED;
221 
222 /* FAT bootsector format, also used by other disk-based derivatives */
223 struct fat_boot_sector {
224     uint8_t bsJump[3];
225     char bsOemName[8];
226     uint16_t bsBytesPerSec;
227     uint8_t bsSecPerClust;
228     uint16_t bsResSectors;
229     uint8_t bsFATs;
230     uint16_t bsRootDirEnts;
231     uint16_t bsSectors;
232     uint8_t bsMedia;
233     uint16_t bsFATsecs;
234     uint16_t bsSecPerTrack;
235     uint16_t bsHeads;
236     uint32_t bsHiddenSecs;
237     uint32_t bsHugeSectors;
238 
239     union {
240 	struct {
241 	    uint8_t DriveNumber;
242 	    uint8_t Reserved1;
243 	    uint8_t BootSignature;
244 	    uint32_t VolumeID;
245 	    char VolumeLabel[11];
246 	    char FileSysType[8];
247 	    uint8_t Code[442];
248 	} PACKED bs16;
249 	struct {
250 	    uint32_t FATSz32;
251 	    uint16_t ExtFlags;
252 	    uint16_t FSVer;
253 	    uint32_t RootClus;
254 	    uint16_t FSInfo;
255 	    uint16_t BkBootSec;
256 	    uint8_t Reserved0[12];
257 	    uint8_t DriveNumber;
258 	    uint8_t Reserved1;
259 	    uint8_t BootSignature;
260 	    uint32_t VolumeID;
261 	    char VolumeLabel[11];
262 	    char FileSysType[8];
263 	    uint8_t Code[414];
264 	} PACKED bs32;
265     } PACKED;
266 
267     uint32_t bsMagic;
268     uint16_t bsForwardPtr;
269     uint16_t bsSignature;
270 } PACKED;
271 
272 /* NTFS bootsector format */
273 struct ntfs_boot_sector {
274     uint8_t bsJump[3];
275     char bsOemName[8];
276     uint16_t bsBytesPerSec;
277     uint8_t bsSecPerClust;
278     uint16_t bsResSectors;
279     uint8_t bsZeroed_0[3];
280     uint16_t bsZeroed_1;
281     uint8_t bsMedia;
282     uint16_t bsZeroed_2;
283     uint16_t bsUnused_0;
284     uint16_t bsUnused_1;
285     uint32_t bsUnused_2;
286     uint32_t bsZeroed_3;
287     uint32_t bsUnused_3;
288     uint64_t bsTotalSectors;
289     uint64_t bsMFTLogicalClustNr;
290     uint64_t bsMFTMirrLogicalClustNr;
291     uint8_t bsClustPerMFTrecord;
292     uint8_t bsUnused_4[3];
293     uint8_t bsClustPerIdxBuf;
294     uint8_t bsUnused_5[3];
295     uint64_t bsVolSerialNr;
296     uint32_t bsUnused_6;
297 
298     uint8_t Code[420];
299 
300     uint32_t bsMagic;
301     uint16_t bsForwardPtr;
302     uint16_t bsSignature;
303 } PACKED;
304 
305 #define FAT_bsHead      bsJump
306 #define FAT_bsHeadLen   offsetof(struct fat_boot_sector, bsBytesPerSec)
307 #define FAT_bsCode	    bs32.Code	/* The common safe choice */
308 #define FAT_bsCodeLen   (offsetof(struct fat_boot_sector, bsSignature) - \
309 		     offsetof(struct fat_boot_sector, FAT_bsCode))
310 
311 #define NTFS_bsHead     bsJump
312 #define NTFS_bsHeadLen  offsetof(struct ntfs_boot_sector, bsOemName)
313 #define NTFS_bsCode     Code
314 #define NTFS_bsCodeLen  (offsetof(struct ntfs_boot_sector, bsSignature) - \
315                             offsetof(struct ntfs_boot_sector, NTFS_bsCode))
316 
317 /* Check if there are specific zero fields in an NTFS boot sector */
ntfs_check_zero_fields(const struct ntfs_boot_sector * sb)318 static inline int ntfs_check_zero_fields(const struct ntfs_boot_sector *sb)
319 {
320     return !sb->bsResSectors && (!sb->bsZeroed_0[0] && !sb->bsZeroed_0[1] &&
321             !sb->bsZeroed_0[2]) && !sb->bsZeroed_1 && !sb->bsZeroed_2 &&
322             !sb->bsZeroed_3;
323 }
324 
ntfs_check_sb_fields(const struct ntfs_boot_sector * sb)325 static inline int ntfs_check_sb_fields(const struct ntfs_boot_sector *sb)
326 {
327     return ntfs_check_zero_fields(sb) &&
328             (!memcmp(sb->bsOemName, "NTFS    ", 8) ||
329              !memcmp(sb->bsOemName, "MSWIN4.0", 8) ||
330              !memcmp(sb->bsOemName, "MSWIN4.1", 8));
331 }
332 
fat_check_sb_fields(const struct fat_boot_sector * sb)333 static inline int fat_check_sb_fields(const struct fat_boot_sector *sb)
334 {
335     return sb->bsResSectors && sb->bsFATs &&
336             (!memcmp(sb->bs16.FileSysType, "FAT12   ", 8) ||
337              !memcmp(sb->bs16.FileSysType, "FAT16   ", 8) ||
338              !memcmp(sb->bs16.FileSysType, "FAT     ", 8) ||
339              !memcmp(sb->bs32.FileSysType, "FAT32   ", 8));
340 }
341 
342 #endif /* SYSLXINT_H */
343