Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / lib / libsys / genhooks / output_i386.c
1 /*
2  * Copyright (c) 2005 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  * 
34  * $DragonFly: src/lib/libsys/genhooks/output_i386.c,v 1.2 2005/12/05 16:48:22 dillon Exp $
35  */
36 /*
37  * OUTPUT_I386.C
38  *
39  * Generate IA32 system call section code for the userland mapping 
40  * area and for the actual map file.
41  */
42
43 #include "defs.h"
44
45 void
46 output_user(FILE *fo)
47 {
48     const char *name;
49     sys_info *sys;
50     int i;
51
52     fprintf(fo, "\t.section DragonFly_%s,\"ax\", @nobits\n", sys_sectname);
53     fprintf(fo, "\t.p2align 12,0\n");
54
55     for (i = 0; i < sys_count; ++i) {
56         sys = sys_array[i];
57         fprintf(fo, "\t.org\t%d * 64\n", i);
58         fprintf(fo, "\t.globl __syscall_%d\n"
59                     "__syscall_%d:\n",
60                     i);
61         if (sys) {
62             name = sys->func_ret->var_name;
63             fprintf(fo, "\t.globl __syscall_%s\n"
64                         "__syscall_%s:\n",
65                         name, name);
66             fprintf(fo, "\t.weak %s\n", name);
67             fprintf(fo, "\t.equ %s, __syscall_%s\n", name, name);
68         }
69         fprintf(fo, "\n");
70     }
71     fprintf(fo, "\t.org\t%d * 64\n", i);
72     fprintf(fo, "\t.p2align 12,0\n");
73 }
74
75 void
76 output_lib(FILE *fo)
77 {
78     sys_info *sys;
79     int i;
80
81     fprintf(fo, "\t.section DragonFly_%s,\"ax\"\n", sys_sectname);
82     fprintf(fo, "\t.p2align 12,0\n");
83
84     for (i = 0; i < sys_count; ++i) {
85         sys = sys_array[i];
86         fprintf(fo, "\t.org\t%d * 64\n", i);
87         fprintf(fo, "\t.globl __syscall_%d\n"
88                     "__syscall_%d:\n",
89                     i);
90         if (sys) {
91             fprintf(fo, "\t.globl __syscall_%s\n"
92                         "__syscall_%s:\n",
93                         sys->func_ret->var_name,
94                         sys->func_ret->var_name);
95             fprintf(fo, "\tlea\t0x%x,%%eax\n"
96                         "\tint\t$0x80\n"
97                         "\tjb\t__syscall_errno_return\n"
98                         "\tret\n",
99                         i);
100         }
101         fprintf(fo, "\n");
102     }
103     fprintf(fo, "\t.org\t%d * 64\n", i);
104     fprintf(fo, "__syscall_errno_return:\n"
105                 "\tmovl\t%%gs:12,%%edx\n"       /* XXX hardwired */
106                 "\tmovl\t%%eax,(%%edx)\n"
107                 "\tmovl\t$-1,%%eax\n"
108                 "\tmovl\t$-1,%%edx\n"
109                 "\tret\n");
110     fprintf(fo, "\t.p2align 12,0\n");
111 }
112
113 void
114 output_standalone(FILE *fo, const char *list_prefix)
115 {
116     const char *name;
117     sys_info *sys;
118     char *path;
119     FILE *fp;
120     int i;
121
122     {
123         asprintf(&path, "%serrno.s", list_prefix);
124         if ((fp = fopen(path, "w")) == NULL) {
125             err(1, "unable to create %s\n", path);
126             /* not reached */
127         }
128         fprintf(fp, "\t.text\n");
129         fprintf(fp, "\t.p2align 4\n");
130         fprintf(fp, "__syscall_errno_return:\n"
131                     "\tmovl\t%%gs:12,%%edx\n"   /* XXX hardwired */
132                     "\tmovl\t%%eax,(%%edx)\n"
133                     "\tmovl\t$-1,%%eax\n"
134                     "\tmovl\t$-1,%%edx\n"
135                     "\tret\n");
136         fclose(fp);
137
138         fprintf(fo, "%s ", path);
139         free(path);
140     }
141
142     for (i = 0; i < sys_count; ++i) {
143         sys = sys_array[i];
144         if (sys == NULL)
145             continue;
146
147         asprintf(&path, "%s%s.s", list_prefix, sys->func_ret->var_name);
148         if ((fp = fopen(path, "w")) == NULL) {
149             err(1, "unable to create %s\n", path);
150             /* not reached */
151         }
152
153         name = sys->func_ret->var_name;
154         fprintf(fp, "\t.text\n");
155         fprintf(fp, "\t.p2align 4\n");
156         fprintf(fp, "\t.globl __syscall_%d\n"
157                     "__syscall_%d:\n", i);
158         fprintf(fp, "\t.globl __syscall_%s\n"
159                     "__syscall_%s:\n",
160                     name, name);
161         fprintf(fp, "\t.weak %s\n", name);
162         fprintf(fp, "\t.equ %s, __syscall_%s\n", name, name);
163         fprintf(fp, "\tlea\t0x%x,%%eax\n"
164                     "\tint\t$0x80\n"
165                     "\tjb\t__syscall_errno_return\n"
166                     "\tret\n",
167                     i);
168         fprintf(fp, "\n");
169         fclose(fp);
170
171         fprintf(fo, " %s", path);
172         free(path);
173     }
174     fprintf(fo, "\n");
175 }
176