88d9c82e724b9d2eb2ee10d62140f59c6a10b4e2
[platform/core/system/edge-orchestration.git] / vendor / golang.org / x / sys / unix / linux / mkall.go
1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // linux/mkall.go - Generates all Linux zsysnum, zsyscall, zerror, and ztype
6 // files for all Linux architectures supported by the go compiler. See
7 // README.md for more information about the build system.
8
9 // To run it you must have a git checkout of the Linux kernel and glibc. Once
10 // the appropriate sources are ready, the program is run as:
11 //     go run linux/mkall.go <linux_dir> <glibc_dir>
12
13 // +build ignore
14
15 package main
16
17 import (
18         "bufio"
19         "bytes"
20         "debug/elf"
21         "encoding/binary"
22         "errors"
23         "fmt"
24         "io"
25         "io/ioutil"
26         "os"
27         "os/exec"
28         "path/filepath"
29         "runtime"
30         "strings"
31         "unicode"
32 )
33
34 // These will be paths to the appropriate source directories.
35 var LinuxDir string
36 var GlibcDir string
37
38 const TempDir = "/tmp"
39 const IncludeDir = TempDir + "/include" // To hold our C headers
40 const BuildDir = TempDir + "/build"     // To hold intermediate build files
41
42 const GOOS = "linux"       // Only for Linux targets
43 const BuildArch = "amd64"  // Must be built on this architecture
44 const MinKernel = "2.6.23" // https://golang.org/doc/install#requirements
45
46 type target struct {
47         GoArch     string // Architecture name according to Go
48         LinuxArch  string // Architecture name according to the Linux Kernel
49         GNUArch    string // Architecture name according to GNU tools (https://wiki.debian.org/Multiarch/Tuples)
50         BigEndian  bool   // Default Little Endian
51         SignedChar bool   // Is -fsigned-char needed (default no)
52         Bits       int
53 }
54
55 // List of all Linux targets supported by the go compiler. Currently, riscv64
56 // and sparc64 are not fully supported, but there is enough support already to
57 // generate Go type and error definitions.
58 var targets = []target{
59         {
60                 GoArch:    "386",
61                 LinuxArch: "x86",
62                 GNUArch:   "i686-linux-gnu", // Note "i686" not "i386"
63                 Bits:      32,
64         },
65         {
66                 GoArch:    "amd64",
67                 LinuxArch: "x86",
68                 GNUArch:   "x86_64-linux-gnu",
69                 Bits:      64,
70         },
71         {
72                 GoArch:     "arm64",
73                 LinuxArch:  "arm64",
74                 GNUArch:    "aarch64-linux-gnu",
75                 SignedChar: true,
76                 Bits:       64,
77         },
78         {
79                 GoArch:    "arm",
80                 LinuxArch: "arm",
81                 GNUArch:   "arm-linux-gnueabi",
82                 Bits:      32,
83         },
84         {
85                 GoArch:    "mips",
86                 LinuxArch: "mips",
87                 GNUArch:   "mips-linux-gnu",
88                 BigEndian: true,
89                 Bits:      32,
90         },
91         {
92                 GoArch:    "mipsle",
93                 LinuxArch: "mips",
94                 GNUArch:   "mipsel-linux-gnu",
95                 Bits:      32,
96         },
97         {
98                 GoArch:    "mips64",
99                 LinuxArch: "mips",
100                 GNUArch:   "mips64-linux-gnuabi64",
101                 BigEndian: true,
102                 Bits:      64,
103         },
104         {
105                 GoArch:    "mips64le",
106                 LinuxArch: "mips",
107                 GNUArch:   "mips64el-linux-gnuabi64",
108                 Bits:      64,
109         },
110         {
111                 GoArch:    "ppc64",
112                 LinuxArch: "powerpc",
113                 GNUArch:   "powerpc64-linux-gnu",
114                 BigEndian: true,
115                 Bits:      64,
116         },
117         {
118                 GoArch:    "ppc64le",
119                 LinuxArch: "powerpc",
120                 GNUArch:   "powerpc64le-linux-gnu",
121                 Bits:      64,
122         },
123         {
124                 GoArch:    "riscv64",
125                 LinuxArch: "riscv",
126                 GNUArch:   "riscv64-linux-gnu",
127                 Bits:      64,
128         },
129         {
130                 GoArch:     "s390x",
131                 LinuxArch:  "s390",
132                 GNUArch:    "s390x-linux-gnu",
133                 BigEndian:  true,
134                 SignedChar: true,
135                 Bits:       64,
136         },
137         {
138                 GoArch:    "sparc64",
139                 LinuxArch: "sparc",
140                 GNUArch:   "sparc64-linux-gnu",
141                 BigEndian: true,
142                 Bits:      64,
143         },
144 }
145
146 // ptracePairs is a list of pairs of targets that can, in some cases,
147 // run each other's binaries.
148 var ptracePairs = []struct{ a1, a2 string }{
149         {"386", "amd64"},
150         {"arm", "arm64"},
151         {"mips", "mips64"},
152         {"mipsle", "mips64le"},
153 }
154
155 func main() {
156         if runtime.GOOS != GOOS || runtime.GOARCH != BuildArch {
157                 fmt.Printf("Build system has GOOS_GOARCH = %s_%s, need %s_%s\n",
158                         runtime.GOOS, runtime.GOARCH, GOOS, BuildArch)
159                 return
160         }
161
162         // Check that we are using the new build system if we should
163         if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
164                 fmt.Println("In the new build system, mkall.go should not be called directly.")
165                 fmt.Println("See README.md")
166                 return
167         }
168
169         // Parse the command line options
170         if len(os.Args) != 3 {
171                 fmt.Println("USAGE: go run linux/mkall.go <linux_dir> <glibc_dir>")
172                 return
173         }
174         LinuxDir = os.Args[1]
175         GlibcDir = os.Args[2]
176
177         for _, t := range targets {
178                 fmt.Printf("----- GENERATING: %s -----\n", t.GoArch)
179                 if err := t.generateFiles(); err != nil {
180                         fmt.Printf("%v\n***** FAILURE:    %s *****\n\n", err, t.GoArch)
181                 } else {
182                         fmt.Printf("----- SUCCESS:    %s -----\n\n", t.GoArch)
183                 }
184         }
185
186         fmt.Printf("----- GENERATING ptrace pairs -----\n")
187         ok := true
188         for _, p := range ptracePairs {
189                 if err := generatePtracePair(p.a1, p.a2); err != nil {
190                         fmt.Printf("%v\n***** FAILURE: %s/%s *****\n\n", err, p.a1, p.a2)
191                         ok = false
192                 }
193         }
194         if ok {
195                 fmt.Printf("----- SUCCESS ptrace pairs    -----\n\n")
196         }
197 }
198
199 // Makes an exec.Cmd with Stderr attached to os.Stderr
200 func makeCommand(name string, args ...string) *exec.Cmd {
201         cmd := exec.Command(name, args...)
202         cmd.Stderr = os.Stderr
203         return cmd
204 }
205
206 // Set GOARCH for target and build environments.
207 func (t *target) setTargetBuildArch(cmd *exec.Cmd) {
208         // Set GOARCH_TARGET so command knows what GOARCH is..
209         cmd.Env = append(os.Environ(), "GOARCH_TARGET="+t.GoArch)
210         // Set GOARCH to host arch for command, so it can run natively.
211         for i, s := range cmd.Env {
212                 if strings.HasPrefix(s, "GOARCH=") {
213                         cmd.Env[i] = "GOARCH=" + BuildArch
214                 }
215         }
216 }
217
218 // Runs the command, pipes output to a formatter, pipes that to an output file.
219 func (t *target) commandFormatOutput(formatter string, outputFile string,
220         name string, args ...string) (err error) {
221         mainCmd := makeCommand(name, args...)
222         if name == "mksyscall" {
223                 args = append([]string{"run", "mksyscall.go"}, args...)
224                 mainCmd = makeCommand("go", args...)
225                 t.setTargetBuildArch(mainCmd)
226         } else if name == "mksysnum" {
227                 args = append([]string{"run", "linux/mksysnum.go"}, args...)
228                 mainCmd = makeCommand("go", args...)
229                 t.setTargetBuildArch(mainCmd)
230         }
231
232         fmtCmd := makeCommand(formatter)
233         if formatter == "mkpost" {
234                 fmtCmd = makeCommand("go", "run", "mkpost.go")
235                 t.setTargetBuildArch(fmtCmd)
236         }
237
238         // mainCmd | fmtCmd > outputFile
239         if fmtCmd.Stdin, err = mainCmd.StdoutPipe(); err != nil {
240                 return
241         }
242         if fmtCmd.Stdout, err = os.Create(outputFile); err != nil {
243                 return
244         }
245
246         // Make sure the formatter eventually closes
247         if err = fmtCmd.Start(); err != nil {
248                 return
249         }
250         defer func() {
251                 fmtErr := fmtCmd.Wait()
252                 if err == nil {
253                         err = fmtErr
254                 }
255         }()
256
257         return mainCmd.Run()
258 }
259
260 // Generates all the files for a Linux target
261 func (t *target) generateFiles() error {
262         // Setup environment variables
263         os.Setenv("GOOS", GOOS)
264         os.Setenv("GOARCH", t.GoArch)
265
266         // Get appropriate compiler and emulator (unless on x86)
267         if t.LinuxArch != "x86" {
268                 // Check/Setup cross compiler
269                 compiler := t.GNUArch + "-gcc"
270                 if _, err := exec.LookPath(compiler); err != nil {
271                         return err
272                 }
273                 os.Setenv("CC", compiler)
274
275                 // Check/Setup emulator (usually first component of GNUArch)
276                 qemuArchName := t.GNUArch[:strings.Index(t.GNUArch, "-")]
277                 if t.LinuxArch == "powerpc" {
278                         qemuArchName = t.GoArch
279                 }
280                 // Fake uname for QEMU to allow running on Host kernel version < 4.15
281                 if t.LinuxArch == "riscv" {
282                         os.Setenv("QEMU_UNAME", "4.15")
283                 }
284                 os.Setenv("GORUN", "qemu-"+qemuArchName)
285         } else {
286                 os.Setenv("CC", "gcc")
287         }
288
289         // Make the include directory and fill it with headers
290         if err := os.MkdirAll(IncludeDir, os.ModePerm); err != nil {
291                 return err
292         }
293         defer os.RemoveAll(IncludeDir)
294         if err := t.makeHeaders(); err != nil {
295                 return fmt.Errorf("could not make header files: %v", err)
296         }
297         fmt.Println("header files generated")
298
299         // Make each of the four files
300         if err := t.makeZSysnumFile(); err != nil {
301                 return fmt.Errorf("could not make zsysnum file: %v", err)
302         }
303         fmt.Println("zsysnum file generated")
304
305         if err := t.makeZSyscallFile(); err != nil {
306                 return fmt.Errorf("could not make zsyscall file: %v", err)
307         }
308         fmt.Println("zsyscall file generated")
309
310         if err := t.makeZTypesFile(); err != nil {
311                 return fmt.Errorf("could not make ztypes file: %v", err)
312         }
313         fmt.Println("ztypes file generated")
314
315         if err := t.makeZErrorsFile(); err != nil {
316                 return fmt.Errorf("could not make zerrors file: %v", err)
317         }
318         fmt.Println("zerrors file generated")
319
320         return nil
321 }
322
323 // Create the Linux, glibc and ABI (C compiler convention) headers in the include directory.
324 func (t *target) makeHeaders() error {
325         // Make the Linux headers we need for this architecture
326         linuxMake := makeCommand("make", "headers_install", "ARCH="+t.LinuxArch, "INSTALL_HDR_PATH="+TempDir)
327         linuxMake.Dir = LinuxDir
328         if err := linuxMake.Run(); err != nil {
329                 return err
330         }
331
332         // A Temporary build directory for glibc
333         if err := os.MkdirAll(BuildDir, os.ModePerm); err != nil {
334                 return err
335         }
336         defer os.RemoveAll(BuildDir)
337
338         // Make the glibc headers we need for this architecture
339         confScript := filepath.Join(GlibcDir, "configure")
340         glibcConf := makeCommand(confScript, "--prefix="+TempDir, "--host="+t.GNUArch, "--enable-kernel="+MinKernel)
341         glibcConf.Dir = BuildDir
342         if err := glibcConf.Run(); err != nil {
343                 return err
344         }
345         glibcMake := makeCommand("make", "install-headers")
346         glibcMake.Dir = BuildDir
347         if err := glibcMake.Run(); err != nil {
348                 return err
349         }
350         // We only need an empty stubs file
351         stubsFile := filepath.Join(IncludeDir, "gnu/stubs.h")
352         if file, err := os.Create(stubsFile); err != nil {
353                 return err
354         } else {
355                 file.Close()
356         }
357
358         // ABI headers will specify C compiler behavior for the target platform.
359         return t.makeABIHeaders()
360 }
361
362 // makeABIHeaders generates C header files based on the platform's calling convention.
363 // While many platforms have formal Application Binary Interfaces, in practice, whatever the
364 // dominant C compilers generate is the de-facto calling convention.
365 //
366 // We generate C headers instead of a Go file, so as to enable references to the ABI from Cgo.
367 func (t *target) makeABIHeaders() (err error) {
368         abiDir := filepath.Join(IncludeDir, "abi")
369         if err = os.Mkdir(abiDir, os.ModePerm); err != nil {
370                 return err
371         }
372
373         cc := os.Getenv("CC")
374         if cc == "" {
375                 return errors.New("CC (compiler) env var not set")
376         }
377
378         // Build a sacrificial ELF file, to mine for C compiler behavior.
379         binPath := filepath.Join(TempDir, "tmp_abi.o")
380         bin, err := t.buildELF(cc, cCode, binPath)
381         if err != nil {
382                 return fmt.Errorf("cannot build ELF to analyze: %v", err)
383         }
384         defer bin.Close()
385         defer os.Remove(binPath)
386
387         // Right now, we put everything in abi.h, but we may change this later.
388         abiFile, err := os.Create(filepath.Join(abiDir, "abi.h"))
389         if err != nil {
390                 return err
391         }
392         defer func() {
393                 if cerr := abiFile.Close(); cerr != nil && err == nil {
394                         err = cerr
395                 }
396         }()
397
398         if err = t.writeBitFieldMasks(bin, abiFile); err != nil {
399                 return fmt.Errorf("cannot write bitfield masks: %v", err)
400         }
401
402         return nil
403 }
404
405 func (t *target) buildELF(cc, src, path string) (*elf.File, error) {
406         // Compile the cCode source using the set compiler - we will need its .data section.
407         // Do not link the binary, so that we can find .data section offsets from the symbol values.
408         ccCmd := makeCommand(cc, "-o", path, "-gdwarf", "-x", "c", "-c", "-")
409         ccCmd.Stdin = strings.NewReader(src)
410         ccCmd.Stdout = os.Stdout
411         if err := ccCmd.Run(); err != nil {
412                 return nil, fmt.Errorf("compiler error: %v", err)
413         }
414
415         bin, err := elf.Open(path)
416         if err != nil {
417                 return nil, fmt.Errorf("cannot read ELF file %s: %v", path, err)
418         }
419
420         return bin, nil
421 }
422
423 func (t *target) writeBitFieldMasks(bin *elf.File, out io.Writer) error {
424         symbols, err := bin.Symbols()
425         if err != nil {
426                 return fmt.Errorf("getting ELF symbols: %v", err)
427         }
428         var masksSym *elf.Symbol
429
430         for _, sym := range symbols {
431                 if sym.Name == "masks" {
432                         masksSym = &sym
433                 }
434         }
435
436         if masksSym == nil {
437                 return errors.New("could not find the 'masks' symbol in ELF symtab")
438         }
439
440         dataSection := bin.Section(".data")
441         if dataSection == nil {
442                 return errors.New("ELF file has no .data section")
443         }
444
445         data, err := dataSection.Data()
446         if err != nil {
447                 return fmt.Errorf("could not read .data section: %v\n", err)
448         }
449
450         var bo binary.ByteOrder
451         if t.BigEndian {
452                 bo = binary.BigEndian
453         } else {
454                 bo = binary.LittleEndian
455         }
456
457         // 64 bit masks of type uint64 are stored in the data section starting at masks.Value.
458         // Here we are running on AMD64, but these values may be big endian or little endian,
459         // depending on target architecture.
460         for i := uint64(0); i < 64; i++ {
461                 off := masksSym.Value + i*8
462                 // Define each mask in native by order, so as to match target endian.
463                 fmt.Fprintf(out, "#define BITFIELD_MASK_%d %dULL\n", i, bo.Uint64(data[off:off+8]))
464         }
465
466         return nil
467 }
468
469 // makes the zsysnum_linux_$GOARCH.go file
470 func (t *target) makeZSysnumFile() error {
471         zsysnumFile := fmt.Sprintf("zsysnum_linux_%s.go", t.GoArch)
472         unistdFile := filepath.Join(IncludeDir, "asm/unistd.h")
473
474         args := append(t.cFlags(), unistdFile)
475         return t.commandFormatOutput("gofmt", zsysnumFile, "mksysnum", args...)
476 }
477
478 // makes the zsyscall_linux_$GOARCH.go file
479 func (t *target) makeZSyscallFile() error {
480         zsyscallFile := fmt.Sprintf("zsyscall_linux_%s.go", t.GoArch)
481         // Find the correct architecture syscall file (might end with x.go)
482         archSyscallFile := fmt.Sprintf("syscall_linux_%s.go", t.GoArch)
483         if _, err := os.Stat(archSyscallFile); os.IsNotExist(err) {
484                 shortArch := strings.TrimSuffix(t.GoArch, "le")
485                 archSyscallFile = fmt.Sprintf("syscall_linux_%sx.go", shortArch)
486         }
487
488         args := append(t.mksyscallFlags(), "-tags", "linux,"+t.GoArch,
489                 "syscall_linux.go", archSyscallFile)
490         return t.commandFormatOutput("gofmt", zsyscallFile, "mksyscall", args...)
491 }
492
493 // makes the zerrors_linux_$GOARCH.go file
494 func (t *target) makeZErrorsFile() error {
495         zerrorsFile := fmt.Sprintf("zerrors_linux_%s.go", t.GoArch)
496
497         return t.commandFormatOutput("gofmt", zerrorsFile, "./mkerrors.sh", t.cFlags()...)
498 }
499
500 // makes the ztypes_linux_$GOARCH.go file
501 func (t *target) makeZTypesFile() error {
502         ztypesFile := fmt.Sprintf("ztypes_linux_%s.go", t.GoArch)
503
504         args := []string{"tool", "cgo", "-godefs", "--"}
505         args = append(args, t.cFlags()...)
506         args = append(args, "linux/types.go")
507         return t.commandFormatOutput("mkpost", ztypesFile, "go", args...)
508 }
509
510 // Flags that should be given to gcc and cgo for this target
511 func (t *target) cFlags() []string {
512         // Compile statically to avoid cross-architecture dynamic linking.
513         flags := []string{"-Wall", "-Werror", "-static", "-I" + IncludeDir}
514
515         // Architecture-specific flags
516         if t.SignedChar {
517                 flags = append(flags, "-fsigned-char")
518         }
519         if t.LinuxArch == "x86" {
520                 flags = append(flags, fmt.Sprintf("-m%d", t.Bits))
521         }
522
523         return flags
524 }
525
526 // Flags that should be given to mksyscall for this target
527 func (t *target) mksyscallFlags() (flags []string) {
528         if t.Bits == 32 {
529                 if t.BigEndian {
530                         flags = append(flags, "-b32")
531                 } else {
532                         flags = append(flags, "-l32")
533                 }
534         }
535
536         // This flag means a 64-bit value should use (even, odd)-pair.
537         if t.GoArch == "arm" || (t.LinuxArch == "mips" && t.Bits == 32) {
538                 flags = append(flags, "-arm")
539         }
540         return
541 }
542
543 // generatePtracePair takes a pair of GOARCH values that can run each
544 // other's binaries, such as 386 and amd64. It extracts the PtraceRegs
545 // type for each one. It writes a new file defining the types
546 // PtraceRegsArch1 and PtraceRegsArch2 and the corresponding functions
547 // Ptrace{Get,Set}Regs{arch1,arch2}. This permits debugging the other
548 // binary on a native system.
549 func generatePtracePair(arch1, arch2 string) error {
550         def1, err := ptraceDef(arch1)
551         if err != nil {
552                 return err
553         }
554         def2, err := ptraceDef(arch2)
555         if err != nil {
556                 return err
557         }
558         f, err := os.Create(fmt.Sprintf("zptrace%s_linux.go", arch1))
559         if err != nil {
560                 return err
561         }
562         buf := bufio.NewWriter(f)
563         fmt.Fprintf(buf, "// Code generated by linux/mkall.go generatePtracePair(%s, %s). DO NOT EDIT.\n", arch1, arch2)
564         fmt.Fprintf(buf, "\n")
565         fmt.Fprintf(buf, "// +build linux\n")
566         fmt.Fprintf(buf, "// +build %s %s\n", arch1, arch2)
567         fmt.Fprintf(buf, "\n")
568         fmt.Fprintf(buf, "package unix\n")
569         fmt.Fprintf(buf, "\n")
570         fmt.Fprintf(buf, "%s\n", `import "unsafe"`)
571         fmt.Fprintf(buf, "\n")
572         writeOnePtrace(buf, arch1, def1)
573         fmt.Fprintf(buf, "\n")
574         writeOnePtrace(buf, arch2, def2)
575         if err := buf.Flush(); err != nil {
576                 return err
577         }
578         if err := f.Close(); err != nil {
579                 return err
580         }
581         return nil
582 }
583
584 // ptraceDef returns the definition of PtraceRegs for arch.
585 func ptraceDef(arch string) (string, error) {
586         filename := fmt.Sprintf("ztypes_linux_%s.go", arch)
587         data, err := ioutil.ReadFile(filename)
588         if err != nil {
589                 return "", fmt.Errorf("reading %s: %v", filename, err)
590         }
591         start := bytes.Index(data, []byte("type PtraceRegs struct"))
592         if start < 0 {
593                 return "", fmt.Errorf("%s: no definition of PtraceRegs", filename)
594         }
595         data = data[start:]
596         end := bytes.Index(data, []byte("\n}\n"))
597         if end < 0 {
598                 return "", fmt.Errorf("%s: can't find end of PtraceRegs definition", filename)
599         }
600         return string(data[:end+2]), nil
601 }
602
603 // writeOnePtrace writes out the ptrace definitions for arch.
604 func writeOnePtrace(w io.Writer, arch, def string) {
605         uarch := string(unicode.ToUpper(rune(arch[0]))) + arch[1:]
606         fmt.Fprintf(w, "// PtraceRegs%s is the registers used by %s binaries.\n", uarch, arch)
607         fmt.Fprintf(w, "%s\n", strings.Replace(def, "PtraceRegs", "PtraceRegs"+uarch, 1))
608         fmt.Fprintf(w, "\n")
609         fmt.Fprintf(w, "// PtraceGetRegs%s fetches the registers used by %s binaries.\n", uarch, arch)
610         fmt.Fprintf(w, "func PtraceGetRegs%s(pid int, regsout *PtraceRegs%s) error {\n", uarch, uarch)
611         fmt.Fprintf(w, "\treturn ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))\n")
612         fmt.Fprintf(w, "}\n")
613         fmt.Fprintf(w, "\n")
614         fmt.Fprintf(w, "// PtraceSetRegs%s sets the registers used by %s binaries.\n", uarch, arch)
615         fmt.Fprintf(w, "func PtraceSetRegs%s(pid int, regs *PtraceRegs%s) error {\n", uarch, uarch)
616         fmt.Fprintf(w, "\treturn ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))\n")
617         fmt.Fprintf(w, "}\n")
618 }
619
620 // cCode is compiled for the target architecture, and the resulting data section is carved for
621 // the statically initialized bit masks.
622 const cCode = `
623 // Bit fields are used in some system calls and other ABIs, but their memory layout is
624 // implementation-defined [1]. Even with formal ABIs, bit fields are a source of subtle bugs [2].
625 // Here we generate the offsets for all 64 bits in an uint64.
626 // 1: http://en.cppreference.com/w/c/language/bit_field
627 // 2: https://lwn.net/Articles/478657/
628
629 #include <stdint.h>
630
631 struct bitfield {
632         union {
633                 uint64_t val;
634                 struct {
635                         uint64_t u64_bit_0 : 1;
636                         uint64_t u64_bit_1 : 1;
637                         uint64_t u64_bit_2 : 1;
638                         uint64_t u64_bit_3 : 1;
639                         uint64_t u64_bit_4 : 1;
640                         uint64_t u64_bit_5 : 1;
641                         uint64_t u64_bit_6 : 1;
642                         uint64_t u64_bit_7 : 1;
643                         uint64_t u64_bit_8 : 1;
644                         uint64_t u64_bit_9 : 1;
645                         uint64_t u64_bit_10 : 1;
646                         uint64_t u64_bit_11 : 1;
647                         uint64_t u64_bit_12 : 1;
648                         uint64_t u64_bit_13 : 1;
649                         uint64_t u64_bit_14 : 1;
650                         uint64_t u64_bit_15 : 1;
651                         uint64_t u64_bit_16 : 1;
652                         uint64_t u64_bit_17 : 1;
653                         uint64_t u64_bit_18 : 1;
654                         uint64_t u64_bit_19 : 1;
655                         uint64_t u64_bit_20 : 1;
656                         uint64_t u64_bit_21 : 1;
657                         uint64_t u64_bit_22 : 1;
658                         uint64_t u64_bit_23 : 1;
659                         uint64_t u64_bit_24 : 1;
660                         uint64_t u64_bit_25 : 1;
661                         uint64_t u64_bit_26 : 1;
662                         uint64_t u64_bit_27 : 1;
663                         uint64_t u64_bit_28 : 1;
664                         uint64_t u64_bit_29 : 1;
665                         uint64_t u64_bit_30 : 1;
666                         uint64_t u64_bit_31 : 1;
667                         uint64_t u64_bit_32 : 1;
668                         uint64_t u64_bit_33 : 1;
669                         uint64_t u64_bit_34 : 1;
670                         uint64_t u64_bit_35 : 1;
671                         uint64_t u64_bit_36 : 1;
672                         uint64_t u64_bit_37 : 1;
673                         uint64_t u64_bit_38 : 1;
674                         uint64_t u64_bit_39 : 1;
675                         uint64_t u64_bit_40 : 1;
676                         uint64_t u64_bit_41 : 1;
677                         uint64_t u64_bit_42 : 1;
678                         uint64_t u64_bit_43 : 1;
679                         uint64_t u64_bit_44 : 1;
680                         uint64_t u64_bit_45 : 1;
681                         uint64_t u64_bit_46 : 1;
682                         uint64_t u64_bit_47 : 1;
683                         uint64_t u64_bit_48 : 1;
684                         uint64_t u64_bit_49 : 1;
685                         uint64_t u64_bit_50 : 1;
686                         uint64_t u64_bit_51 : 1;
687                         uint64_t u64_bit_52 : 1;
688                         uint64_t u64_bit_53 : 1;
689                         uint64_t u64_bit_54 : 1;
690                         uint64_t u64_bit_55 : 1;
691                         uint64_t u64_bit_56 : 1;
692                         uint64_t u64_bit_57 : 1;
693                         uint64_t u64_bit_58 : 1;
694                         uint64_t u64_bit_59 : 1;
695                         uint64_t u64_bit_60 : 1;
696                         uint64_t u64_bit_61 : 1;
697                         uint64_t u64_bit_62 : 1;
698                         uint64_t u64_bit_63 : 1;
699                 };
700         };
701 };
702
703 struct bitfield masks[] = {
704         {.u64_bit_0 = 1},
705         {.u64_bit_1 = 1},
706         {.u64_bit_2 = 1},
707         {.u64_bit_3 = 1},
708         {.u64_bit_4 = 1},
709         {.u64_bit_5 = 1},
710         {.u64_bit_6 = 1},
711         {.u64_bit_7 = 1},
712         {.u64_bit_8 = 1},
713         {.u64_bit_9 = 1},
714         {.u64_bit_10 = 1},
715         {.u64_bit_11 = 1},
716         {.u64_bit_12 = 1},
717         {.u64_bit_13 = 1},
718         {.u64_bit_14 = 1},
719         {.u64_bit_15 = 1},
720         {.u64_bit_16 = 1},
721         {.u64_bit_17 = 1},
722         {.u64_bit_18 = 1},
723         {.u64_bit_19 = 1},
724         {.u64_bit_20 = 1},
725         {.u64_bit_21 = 1},
726         {.u64_bit_22 = 1},
727         {.u64_bit_23 = 1},
728         {.u64_bit_24 = 1},
729         {.u64_bit_25 = 1},
730         {.u64_bit_26 = 1},
731         {.u64_bit_27 = 1},
732         {.u64_bit_28 = 1},
733         {.u64_bit_29 = 1},
734         {.u64_bit_30 = 1},
735         {.u64_bit_31 = 1},
736         {.u64_bit_32 = 1},
737         {.u64_bit_33 = 1},
738         {.u64_bit_34 = 1},
739         {.u64_bit_35 = 1},
740         {.u64_bit_36 = 1},
741         {.u64_bit_37 = 1},
742         {.u64_bit_38 = 1},
743         {.u64_bit_39 = 1},
744         {.u64_bit_40 = 1},
745         {.u64_bit_41 = 1},
746         {.u64_bit_42 = 1},
747         {.u64_bit_43 = 1},
748         {.u64_bit_44 = 1},
749         {.u64_bit_45 = 1},
750         {.u64_bit_46 = 1},
751         {.u64_bit_47 = 1},
752         {.u64_bit_48 = 1},
753         {.u64_bit_49 = 1},
754         {.u64_bit_50 = 1},
755         {.u64_bit_51 = 1},
756         {.u64_bit_52 = 1},
757         {.u64_bit_53 = 1},
758         {.u64_bit_54 = 1},
759         {.u64_bit_55 = 1},
760         {.u64_bit_56 = 1},
761         {.u64_bit_57 = 1},
762         {.u64_bit_58 = 1},
763         {.u64_bit_59 = 1},
764         {.u64_bit_60 = 1},
765         {.u64_bit_61 = 1},
766         {.u64_bit_62 = 1},
767         {.u64_bit_63 = 1}
768 };
769
770 int main(int argc, char **argv) {
771         struct bitfield *mask_ptr = &masks[0];
772         return mask_ptr->val;
773 }
774
775 `