diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/ppc64/boot |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/ppc64/boot')
-rw-r--r-- | arch/ppc64/boot/Makefile | 117 | ||||
-rw-r--r-- | arch/ppc64/boot/README | 11 | ||||
-rw-r--r-- | arch/ppc64/boot/addRamDisk.c | 300 | ||||
-rw-r--r-- | arch/ppc64/boot/addnote.c | 165 | ||||
-rw-r--r-- | arch/ppc64/boot/crt0.S | 48 | ||||
-rw-r--r-- | arch/ppc64/boot/div64.S | 58 | ||||
-rw-r--r-- | arch/ppc64/boot/install.sh | 42 | ||||
-rw-r--r-- | arch/ppc64/boot/main.c | 331 | ||||
-rw-r--r-- | arch/ppc64/boot/mknote.c | 43 | ||||
-rw-r--r-- | arch/ppc64/boot/piggyback.c | 83 | ||||
-rw-r--r-- | arch/ppc64/boot/ppc32-types.h | 36 | ||||
-rw-r--r-- | arch/ppc64/boot/prom.c | 637 | ||||
-rw-r--r-- | arch/ppc64/boot/start.c | 654 | ||||
-rw-r--r-- | arch/ppc64/boot/string.S | 216 | ||||
-rw-r--r-- | arch/ppc64/boot/zImage.lds | 90 | ||||
-rw-r--r-- | arch/ppc64/boot/zlib.c | 2194 | ||||
-rw-r--r-- | arch/ppc64/boot/zlib.h | 432 |
17 files changed, 5457 insertions, 0 deletions
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile new file mode 100644 index 00000000000..d3e1d6af920 --- /dev/null +++ b/arch/ppc64/boot/Makefile | |||
@@ -0,0 +1,117 @@ | |||
1 | # Makefile for making ELF bootable images for booting on CHRP | ||
2 | # using Open Firmware. | ||
3 | # | ||
4 | # Geert Uytterhoeven September 1997 | ||
5 | # | ||
6 | # Based on coffboot by Paul Mackerras | ||
7 | # Simplified for ppc64 by Todd Inglett | ||
8 | # | ||
9 | # NOTE: this code is built for 32 bit in ELF32 format even though | ||
10 | # it packages a 64 bit kernel. We do this to simplify the | ||
11 | # bootloader and increase compatibility with OpenFirmware. | ||
12 | # | ||
13 | # To this end we need to define BOOTCC, etc, as the tools | ||
14 | # needed to build the 32 bit image. These are normally HOSTCC, | ||
15 | # but may be a third compiler if, for example, you are cross | ||
16 | # compiling from an intel box. Once the 64bit ppc gcc is | ||
17 | # stable it will probably simply be a compiler switch to | ||
18 | # compile for 32bit mode. | ||
19 | # To make it easier to setup a cross compiler, | ||
20 | # CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE | ||
21 | # in the toplevel makefile. | ||
22 | |||
23 | |||
24 | HOSTCC := gcc | ||
25 | BOOTCFLAGS := $(HOSTCFLAGS) $(LINUXINCLUDE) -fno-builtin | ||
26 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional | ||
27 | BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds | ||
28 | OBJCOPYFLAGS := contents,alloc,load,readonly,data | ||
29 | |||
30 | src-boot := crt0.S string.S prom.c main.c zlib.c imagesize.c div64.S | ||
31 | src-boot := $(addprefix $(obj)/, $(src-boot)) | ||
32 | obj-boot := $(addsuffix .o, $(basename $(src-boot))) | ||
33 | |||
34 | quiet_cmd_bootcc = BOOTCC $@ | ||
35 | cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< | ||
36 | |||
37 | quiet_cmd_bootas = BOOTAS $@ | ||
38 | cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< | ||
39 | |||
40 | $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c | ||
41 | $(call if_changed_dep,bootcc) | ||
42 | $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S | ||
43 | $(call if_changed_dep,bootas) | ||
44 | |||
45 | #----------------------------------------------------------- | ||
46 | # ELF sections within the zImage bootloader/wrapper | ||
47 | #----------------------------------------------------------- | ||
48 | required := vmlinux.strip | ||
49 | initrd := initrd | ||
50 | |||
51 | obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section))) | ||
52 | src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) | ||
53 | gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) | ||
54 | |||
55 | hostprogs-y := piggy addnote addRamDisk | ||
56 | targets += zImage zImage.initrd imagesize.c \ | ||
57 | $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ | ||
58 | $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ | ||
59 | $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ | ||
60 | vmlinux.initrd | ||
61 | extra-y := initrd.o | ||
62 | |||
63 | quiet_cmd_ramdisk = RAMDISK $@ | ||
64 | cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@ | ||
65 | |||
66 | quiet_cmd_stripvm = STRIP $@ | ||
67 | cmd_stripvm = $(STRIP) -s $< -o $@ | ||
68 | |||
69 | vmlinux.strip: vmlinux FORCE | ||
70 | $(call if_changed,stripvm) | ||
71 | $(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE | ||
72 | $(call if_changed,ramdisk) | ||
73 | |||
74 | addsection = $(CROSS32OBJCOPY) $(1) \ | ||
75 | --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \ | ||
76 | --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS) | ||
77 | |||
78 | quiet_cmd_addnote = ADDNOTE $@ | ||
79 | cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ | ||
80 | |||
81 | quiet_cmd_piggy = PIGGY $@ | ||
82 | cmd_piggy = $(obj)/piggyback $(@:.o=) < $< | $(CROSS32AS) -o $@ | ||
83 | |||
84 | $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE | ||
85 | $(call if_changed,gzip) | ||
86 | |||
87 | $(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz | ||
88 | cp -f $(obj)/ramdisk.image.gz $@ | ||
89 | |||
90 | $(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE | ||
91 | touch $@ | ||
92 | |||
93 | $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE | ||
94 | $(call if_changed_dep,bootcc) | ||
95 | $(call addsection, $@) | ||
96 | |||
97 | $(obj)/zImage: obj-boot += $(call obj-sec, $(required)) | ||
98 | $(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) $(obj)/addnote FORCE | ||
99 | $(call if_changed,addnote) | ||
100 | |||
101 | $(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd)) | ||
102 | $(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE | ||
103 | $(call if_changed,addnote) | ||
104 | |||
105 | $(obj)/imagesize.c: vmlinux.strip | ||
106 | @echo Generating $@ | ||
107 | ls -l vmlinux.strip | \ | ||
108 | awk '{printf "/* generated -- do not edit! */\n" \ | ||
109 | "unsigned long vmlinux_filesize = %d;\n", $$5}' > $(obj)/imagesize.c | ||
110 | $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \ | ||
111 | awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' \ | ||
112 | >> $(obj)/imagesize.c | ||
113 | |||
114 | install: $(CONFIGURE) $(BOOTIMAGE) | ||
115 | sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" | ||
116 | |||
117 | clean-files := $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip) | ||
diff --git a/arch/ppc64/boot/README b/arch/ppc64/boot/README new file mode 100644 index 00000000000..3e11058760e --- /dev/null +++ b/arch/ppc64/boot/README | |||
@@ -0,0 +1,11 @@ | |||
1 | |||
2 | To extract the kernel vmlinux, System.map, .config or initrd from the zImage binary: | ||
3 | |||
4 | objcopy -j .kernel:vmlinux -O binary zImage vmlinux.gz | ||
5 | objcopy -j .kernel:System.map -O binary zImage System.map.gz | ||
6 | objcopy -j .kernel:.config -O binary zImage config.gz | ||
7 | objcopy -j .kernel:initrd -O binary zImage.initrd initrd.gz | ||
8 | |||
9 | |||
10 | Peter | ||
11 | |||
diff --git a/arch/ppc64/boot/addRamDisk.c b/arch/ppc64/boot/addRamDisk.c new file mode 100644 index 00000000000..7f2c0947339 --- /dev/null +++ b/arch/ppc64/boot/addRamDisk.c | |||
@@ -0,0 +1,300 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <netinet/in.h> | ||
4 | #include <unistd.h> | ||
5 | #include <sys/types.h> | ||
6 | #include <sys/stat.h> | ||
7 | #include <string.h> | ||
8 | |||
9 | #define ElfHeaderSize (64 * 1024) | ||
10 | #define ElfPages (ElfHeaderSize / 4096) | ||
11 | #define KERNELBASE (0xc000000000000000) | ||
12 | |||
13 | void get4k(FILE *file, char *buf ) | ||
14 | { | ||
15 | unsigned j; | ||
16 | unsigned num = fread(buf, 1, 4096, file); | ||
17 | for ( j=num; j<4096; ++j ) | ||
18 | buf[j] = 0; | ||
19 | } | ||
20 | |||
21 | void put4k(FILE *file, char *buf ) | ||
22 | { | ||
23 | fwrite(buf, 1, 4096, file); | ||
24 | } | ||
25 | |||
26 | void death(const char *msg, FILE *fdesc, const char *fname) | ||
27 | { | ||
28 | fprintf(stderr, msg); | ||
29 | fclose(fdesc); | ||
30 | unlink(fname); | ||
31 | exit(1); | ||
32 | } | ||
33 | |||
34 | int main(int argc, char **argv) | ||
35 | { | ||
36 | char inbuf[4096]; | ||
37 | FILE *ramDisk = NULL; | ||
38 | FILE *sysmap = NULL; | ||
39 | FILE *inputVmlinux = NULL; | ||
40 | FILE *outputVmlinux = NULL; | ||
41 | |||
42 | unsigned i = 0; | ||
43 | unsigned long ramFileLen = 0; | ||
44 | unsigned long ramLen = 0; | ||
45 | unsigned long roundR = 0; | ||
46 | |||
47 | unsigned long sysmapFileLen = 0; | ||
48 | unsigned long sysmapLen = 0; | ||
49 | unsigned long sysmapPages = 0; | ||
50 | char* ptr_end = NULL; | ||
51 | unsigned long offset_end = 0; | ||
52 | |||
53 | unsigned long kernelLen = 0; | ||
54 | unsigned long actualKernelLen = 0; | ||
55 | unsigned long round = 0; | ||
56 | unsigned long roundedKernelLen = 0; | ||
57 | unsigned long ramStartOffs = 0; | ||
58 | unsigned long ramPages = 0; | ||
59 | unsigned long roundedKernelPages = 0; | ||
60 | unsigned long hvReleaseData = 0; | ||
61 | u_int32_t eyeCatcher = 0xc8a5d9c4; | ||
62 | unsigned long naca = 0; | ||
63 | unsigned long xRamDisk = 0; | ||
64 | unsigned long xRamDiskSize = 0; | ||
65 | long padPages = 0; | ||
66 | |||
67 | |||
68 | if (argc < 2) { | ||
69 | fprintf(stderr, "Name of RAM disk file missing.\n"); | ||
70 | exit(1); | ||
71 | } | ||
72 | |||
73 | if (argc < 3) { | ||
74 | fprintf(stderr, "Name of System Map input file is missing.\n"); | ||
75 | exit(1); | ||
76 | } | ||
77 | |||
78 | if (argc < 4) { | ||
79 | fprintf(stderr, "Name of vmlinux file missing.\n"); | ||
80 | exit(1); | ||
81 | } | ||
82 | |||
83 | if (argc < 5) { | ||
84 | fprintf(stderr, "Name of vmlinux output file missing.\n"); | ||
85 | exit(1); | ||
86 | } | ||
87 | |||
88 | |||
89 | ramDisk = fopen(argv[1], "r"); | ||
90 | if ( ! ramDisk ) { | ||
91 | fprintf(stderr, "RAM disk file \"%s\" failed to open.\n", argv[1]); | ||
92 | exit(1); | ||
93 | } | ||
94 | |||
95 | sysmap = fopen(argv[2], "r"); | ||
96 | if ( ! sysmap ) { | ||
97 | fprintf(stderr, "System Map file \"%s\" failed to open.\n", argv[2]); | ||
98 | exit(1); | ||
99 | } | ||
100 | |||
101 | inputVmlinux = fopen(argv[3], "r"); | ||
102 | if ( ! inputVmlinux ) { | ||
103 | fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", argv[3]); | ||
104 | exit(1); | ||
105 | } | ||
106 | |||
107 | outputVmlinux = fopen(argv[4], "w+"); | ||
108 | if ( ! outputVmlinux ) { | ||
109 | fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", argv[4]); | ||
110 | exit(1); | ||
111 | } | ||
112 | |||
113 | |||
114 | |||
115 | /* Input Vmlinux file */ | ||
116 | fseek(inputVmlinux, 0, SEEK_END); | ||
117 | kernelLen = ftell(inputVmlinux); | ||
118 | fseek(inputVmlinux, 0, SEEK_SET); | ||
119 | printf("kernel file size = %d\n", kernelLen); | ||
120 | if ( kernelLen == 0 ) { | ||
121 | fprintf(stderr, "You must have a linux kernel specified as argv[3]\n"); | ||
122 | exit(1); | ||
123 | } | ||
124 | |||
125 | actualKernelLen = kernelLen - ElfHeaderSize; | ||
126 | |||
127 | printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen); | ||
128 | |||
129 | round = actualKernelLen % 4096; | ||
130 | roundedKernelLen = actualKernelLen; | ||
131 | if ( round ) | ||
132 | roundedKernelLen += (4096 - round); | ||
133 | printf("Vmlinux length rounded up to a 4k multiple = %ld/0x%lx \n", roundedKernelLen, roundedKernelLen); | ||
134 | roundedKernelPages = roundedKernelLen / 4096; | ||
135 | printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages); | ||
136 | |||
137 | |||
138 | |||
139 | /* Input System Map file */ | ||
140 | /* (needs to be processed simply to determine if we need to add pad pages due to the static variables not being included in the vmlinux) */ | ||
141 | fseek(sysmap, 0, SEEK_END); | ||
142 | sysmapFileLen = ftell(sysmap); | ||
143 | fseek(sysmap, 0, SEEK_SET); | ||
144 | printf("%s file size = %ld/0x%lx \n", argv[2], sysmapFileLen, sysmapFileLen); | ||
145 | |||
146 | sysmapLen = sysmapFileLen; | ||
147 | |||
148 | roundR = 4096 - (sysmapLen % 4096); | ||
149 | if (roundR) { | ||
150 | printf("Rounding System Map file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR); | ||
151 | sysmapLen += roundR; | ||
152 | } | ||
153 | printf("Rounded System Map size is %ld/0x%lx \n", sysmapLen, sysmapLen); | ||
154 | |||
155 | /* Process the Sysmap file to determine where _end is */ | ||
156 | sysmapPages = sysmapLen / 4096; | ||
157 | /* read the whole file line by line, expect that it doesn't fail */ | ||
158 | while ( fgets(inbuf, 4096, sysmap) ) ; | ||
159 | /* search for _end in the last page of the system map */ | ||
160 | ptr_end = strstr(inbuf, " _end"); | ||
161 | if (!ptr_end) { | ||
162 | fprintf(stderr, "Unable to find _end in the sysmap file \n"); | ||
163 | fprintf(stderr, "inbuf: \n"); | ||
164 | fprintf(stderr, "%s \n", inbuf); | ||
165 | exit(1); | ||
166 | } | ||
167 | printf("Found _end in the last page of the sysmap - backing up 10 characters it looks like %s", ptr_end-10); | ||
168 | /* convert address of _end in system map to hex offset. */ | ||
169 | offset_end = (unsigned int)strtol(ptr_end-10, NULL, 16); | ||
170 | /* calc how many pages we need to insert between the vmlinux and the start of the ram disk */ | ||
171 | padPages = offset_end/4096 - roundedKernelPages; | ||
172 | |||
173 | /* Check and see if the vmlinux is already larger than _end in System.map */ | ||
174 | if (padPages < 0) { | ||
175 | /* vmlinux is larger than _end - adjust the offset to the start of the embedded ram disk */ | ||
176 | offset_end = roundedKernelLen; | ||
177 | printf("vmlinux is larger than _end indicates it needs to be - offset_end = %lx \n", offset_end); | ||
178 | padPages = 0; | ||
179 | printf("will insert %lx pages between the vmlinux and the start of the ram disk \n", padPages); | ||
180 | } | ||
181 | else { | ||
182 | /* _end is larger than vmlinux - use the offset to _end that we calculated from the system map */ | ||
183 | printf("vmlinux is smaller than _end indicates is needed - offset_end = %lx \n", offset_end); | ||
184 | printf("will insert %lx pages between the vmlinux and the start of the ram disk \n", padPages); | ||
185 | } | ||
186 | |||
187 | |||
188 | |||
189 | /* Input Ram Disk file */ | ||
190 | // Set the offset that the ram disk will be started at. | ||
191 | ramStartOffs = offset_end; /* determined from the input vmlinux file and the system map */ | ||
192 | printf("Ram Disk will start at offset = 0x%lx \n", ramStartOffs); | ||
193 | |||
194 | fseek(ramDisk, 0, SEEK_END); | ||
195 | ramFileLen = ftell(ramDisk); | ||
196 | fseek(ramDisk, 0, SEEK_SET); | ||
197 | printf("%s file size = %ld/0x%lx \n", argv[1], ramFileLen, ramFileLen); | ||
198 | |||
199 | ramLen = ramFileLen; | ||
200 | |||
201 | roundR = 4096 - (ramLen % 4096); | ||
202 | if ( roundR ) { | ||
203 | printf("Rounding RAM disk file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR); | ||
204 | ramLen += roundR; | ||
205 | } | ||
206 | |||
207 | printf("Rounded RAM disk size is %ld/0x%lx \n", ramLen, ramLen); | ||
208 | ramPages = ramLen / 4096; | ||
209 | printf("RAM disk pages to copy = %ld/0x%lx\n", ramPages, ramPages); | ||
210 | |||
211 | |||
212 | |||
213 | // Copy 64K ELF header | ||
214 | for (i=0; i<(ElfPages); ++i) { | ||
215 | get4k( inputVmlinux, inbuf ); | ||
216 | put4k( outputVmlinux, inbuf ); | ||
217 | } | ||
218 | |||
219 | /* Copy the vmlinux (as full pages). */ | ||
220 | fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); | ||
221 | for ( i=0; i<roundedKernelPages; ++i ) { | ||
222 | get4k( inputVmlinux, inbuf ); | ||
223 | put4k( outputVmlinux, inbuf ); | ||
224 | } | ||
225 | |||
226 | /* Insert pad pages (if appropriate) that are needed between */ | ||
227 | /* | the end of the vmlinux and the ram disk. */ | ||
228 | for (i=0; i<padPages; ++i) { | ||
229 | memset(inbuf, 0, 4096); | ||
230 | put4k(outputVmlinux, inbuf); | ||
231 | } | ||
232 | |||
233 | /* Copy the ram disk (as full pages). */ | ||
234 | for ( i=0; i<ramPages; ++i ) { | ||
235 | get4k( ramDisk, inbuf ); | ||
236 | put4k( outputVmlinux, inbuf ); | ||
237 | } | ||
238 | |||
239 | /* Close the input files */ | ||
240 | fclose(ramDisk); | ||
241 | fclose(inputVmlinux); | ||
242 | /* And flush the written output file */ | ||
243 | fflush(outputVmlinux); | ||
244 | |||
245 | |||
246 | |||
247 | /* Fixup the new vmlinux to contain the ram disk starting offset (xRamDisk) and the ram disk size (xRamDiskSize) */ | ||
248 | /* fseek to the hvReleaseData pointer */ | ||
249 | fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET); | ||
250 | if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) { | ||
251 | death("Could not read hvReleaseData pointer\n", outputVmlinux, argv[4]); | ||
252 | } | ||
253 | hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */ | ||
254 | printf("hvReleaseData is at %08x\n", hvReleaseData); | ||
255 | |||
256 | /* fseek to the hvReleaseData */ | ||
257 | fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET); | ||
258 | if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) { | ||
259 | death("Could not read hvReleaseData\n", outputVmlinux, argv[4]); | ||
260 | } | ||
261 | /* Check hvReleaseData sanity */ | ||
262 | if (memcmp(inbuf, &eyeCatcher, 4) != 0) { | ||
263 | death("hvReleaseData is invalid\n", outputVmlinux, argv[4]); | ||
264 | } | ||
265 | /* Get the naca pointer */ | ||
266 | naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE; | ||
267 | printf("Naca is at offset 0x%lx \n", naca); | ||
268 | |||
269 | /* fseek to the naca */ | ||
270 | fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); | ||
271 | if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) { | ||
272 | death("Could not read naca\n", outputVmlinux, argv[4]); | ||
273 | } | ||
274 | xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c])); | ||
275 | xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14])); | ||
276 | /* Make sure a RAM disk isn't already present */ | ||
277 | if ((xRamDisk != 0) || (xRamDiskSize != 0)) { | ||
278 | death("RAM disk is already attached to this kernel\n", outputVmlinux, argv[4]); | ||
279 | } | ||
280 | /* Fill in the values */ | ||
281 | *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs); | ||
282 | *((u_int32_t *) &inbuf[0x14]) = htonl(ramPages); | ||
283 | |||
284 | /* Write out the new naca */ | ||
285 | fflush(outputVmlinux); | ||
286 | fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); | ||
287 | if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) { | ||
288 | death("Could not write naca\n", outputVmlinux, argv[4]); | ||
289 | } | ||
290 | printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08x\n", | ||
291 | ramPages, ramStartOffs); | ||
292 | |||
293 | /* Done */ | ||
294 | fclose(outputVmlinux); | ||
295 | /* Set permission to executable */ | ||
296 | chmod(argv[4], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); | ||
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||
diff --git a/arch/ppc64/boot/addnote.c b/arch/ppc64/boot/addnote.c new file mode 100644 index 00000000000..66ff8103bf4 --- /dev/null +++ b/arch/ppc64/boot/addnote.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * Program to hack in a PT_NOTE program header entry in an ELF file. | ||
3 | * This is needed for OF on RS/6000s to load an image correctly. | ||
4 | * Note that OF needs a program header entry for the note, not an | ||
5 | * ELF section. | ||
6 | * | ||
7 | * Copyright 2000 Paul Mackerras. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | * | ||
14 | * Usage: addnote zImage | ||
15 | */ | ||
16 | #include <stdio.h> | ||
17 | #include <stdlib.h> | ||
18 | #include <fcntl.h> | ||
19 | #include <unistd.h> | ||
20 | #include <string.h> | ||
21 | |||
22 | char arch[] = "PowerPC"; | ||
23 | |||
24 | #define N_DESCR 6 | ||
25 | unsigned int descr[N_DESCR] = { | ||
26 | 0xffffffff, /* real-mode = true */ | ||
27 | 0x00c00000, /* real-base, i.e. where we expect OF to be */ | ||
28 | 0xffffffff, /* real-size */ | ||
29 | 0xffffffff, /* virt-base */ | ||
30 | 0xffffffff, /* virt-size */ | ||
31 | 0x4000, /* load-base */ | ||
32 | }; | ||
33 | |||
34 | unsigned char buf[512]; | ||
35 | |||
36 | #define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) | ||
37 | #define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2)) | ||
38 | |||
39 | #define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \ | ||
40 | buf[(off) + 1] = (v) & 0xff) | ||
41 | #define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \ | ||
42 | PUT_16BE((off) + 2, (v))) | ||
43 | |||
44 | /* Structure of an ELF file */ | ||
45 | #define E_IDENT 0 /* ELF header */ | ||
46 | #define E_PHOFF 28 | ||
47 | #define E_PHENTSIZE 42 | ||
48 | #define E_PHNUM 44 | ||
49 | #define E_HSIZE 52 /* size of ELF header */ | ||
50 | |||
51 | #define EI_MAGIC 0 /* offsets in E_IDENT area */ | ||
52 | #define EI_CLASS 4 | ||
53 | #define EI_DATA 5 | ||
54 | |||
55 | #define PH_TYPE 0 /* ELF program header */ | ||
56 | #define PH_OFFSET 4 | ||
57 | #define PH_FILESZ 16 | ||
58 | #define PH_HSIZE 32 /* size of program header */ | ||
59 | |||
60 | #define PT_NOTE 4 /* Program header type = note */ | ||
61 | |||
62 | #define ELFCLASS32 1 | ||
63 | #define ELFDATA2MSB 2 | ||
64 | |||
65 | unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; | ||
66 | |||
67 | int | ||
68 | main(int ac, char **av) | ||
69 | { | ||
70 | int fd, n, i; | ||
71 | int ph, ps, np; | ||
72 | int nnote, ns; | ||
73 | |||
74 | if (ac != 2) { | ||
75 | fprintf(stderr, "Usage: %s elf-file\n", av[0]); | ||
76 | exit(1); | ||
77 | } | ||
78 | fd = open(av[1], O_RDWR); | ||
79 | if (fd < 0) { | ||
80 | perror(av[1]); | ||
81 | exit(1); | ||
82 | } | ||
83 | |||
84 | nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4; | ||
85 | |||
86 | n = read(fd, buf, sizeof(buf)); | ||
87 | if (n < 0) { | ||
88 | perror("read"); | ||
89 | exit(1); | ||
90 | } | ||
91 | |||
92 | if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0) | ||
93 | goto notelf; | ||
94 | |||
95 | if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 | ||
96 | || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { | ||
97 | fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", | ||
98 | av[1]); | ||
99 | exit(1); | ||
100 | } | ||
101 | |||
102 | ph = GET_32BE(E_PHOFF); | ||
103 | ps = GET_16BE(E_PHENTSIZE); | ||
104 | np = GET_16BE(E_PHNUM); | ||
105 | if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) | ||
106 | goto notelf; | ||
107 | if (ph + (np + 1) * ps + nnote > n) | ||
108 | goto nospace; | ||
109 | |||
110 | for (i = 0; i < np; ++i) { | ||
111 | if (GET_32BE(ph + PH_TYPE) == PT_NOTE) { | ||
112 | fprintf(stderr, "%s already has a note entry\n", | ||
113 | av[1]); | ||
114 | exit(0); | ||
115 | } | ||
116 | ph += ps; | ||
117 | } | ||
118 | |||
119 | /* XXX check that the area we want to use is all zeroes */ | ||
120 | for (i = 0; i < ps + nnote; ++i) | ||
121 | if (buf[ph + i] != 0) | ||
122 | goto nospace; | ||
123 | |||
124 | /* fill in the program header entry */ | ||
125 | ns = ph + ps; | ||
126 | PUT_32BE(ph + PH_TYPE, PT_NOTE); | ||
127 | PUT_32BE(ph + PH_OFFSET, ns); | ||
128 | PUT_32BE(ph + PH_FILESZ, nnote); | ||
129 | |||
130 | /* fill in the note area we point to */ | ||
131 | /* XXX we should probably make this a proper section */ | ||
132 | PUT_32BE(ns, strlen(arch) + 1); | ||
133 | PUT_32BE(ns + 4, N_DESCR * 4); | ||
134 | PUT_32BE(ns + 8, 0x1275); | ||
135 | strcpy(&buf[ns + 12], arch); | ||
136 | ns += 12 + strlen(arch) + 1; | ||
137 | for (i = 0; i < N_DESCR; ++i) | ||
138 | PUT_32BE(ns + i * 4, descr[i]); | ||
139 | |||
140 | /* Update the number of program headers */ | ||
141 | PUT_16BE(E_PHNUM, np + 1); | ||
142 | |||
143 | /* write back */ | ||
144 | lseek(fd, (long) 0, SEEK_SET); | ||
145 | i = write(fd, buf, n); | ||
146 | if (i < 0) { | ||
147 | perror("write"); | ||
148 | exit(1); | ||
149 | } | ||
150 | if (i < n) { | ||
151 | fprintf(stderr, "%s: write truncated\n", av[1]); | ||
152 | exit(1); | ||
153 | } | ||
154 | |||
155 | exit(0); | ||
156 | |||
157 | notelf: | ||
158 | fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]); | ||
159 | exit(1); | ||
160 | |||
161 | nospace: | ||
162 | fprintf(stderr, "sorry, I can't find space in %s to put the note\n", | ||
163 | av[0]); | ||
164 | exit(1); | ||
165 | } | ||
diff --git a/arch/ppc64/boot/crt0.S b/arch/ppc64/boot/crt0.S new file mode 100644 index 00000000000..04d3e74cd72 --- /dev/null +++ b/arch/ppc64/boot/crt0.S | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * NOTE: this code runs in 32 bit mode and is packaged as ELF32. | ||
10 | */ | ||
11 | |||
12 | #include <asm/ppc_asm.h> | ||
13 | |||
14 | .text | ||
15 | .globl _start | ||
16 | _start: | ||
17 | lis r9,_start@h | ||
18 | lis r8,_etext@ha | ||
19 | addi r8,r8,_etext@l | ||
20 | 1: dcbf r0,r9 | ||
21 | icbi r0,r9 | ||
22 | addi r9,r9,0x20 | ||
23 | cmplwi 0,r9,8 | ||
24 | blt 1b | ||
25 | sync | ||
26 | isync | ||
27 | |||
28 | ## Clear out the BSS as per ANSI C requirements | ||
29 | |||
30 | lis r7,_end@ha | ||
31 | addi r7,r7,_end@l # r7 = &_end | ||
32 | lis r8,__bss_start@ha # | ||
33 | addi r8,r8,__bss_start@l # r8 = &_bss_start | ||
34 | |||
35 | ## Determine how large an area, in number of words, to clear | ||
36 | |||
37 | subf r7,r8,r7 # r7 = &_end - &_bss_start + 1 | ||
38 | addi r7,r7,3 # r7 += 3 | ||
39 | srwi. r7,r7,2 # r7 = size in words. | ||
40 | beq 3f # If the size is zero, don't bother | ||
41 | addi r8,r8,-4 # r8 -= 4 | ||
42 | mtctr r7 # SPRN_CTR = number of words to clear | ||
43 | li r0,0 # r0 = 0 | ||
44 | 2: stwu r0,4(r8) # Clear out a word | ||
45 | bdnz 2b # Keep clearing until done | ||
46 | 3: | ||
47 | b start | ||
48 | |||
diff --git a/arch/ppc64/boot/div64.S b/arch/ppc64/boot/div64.S new file mode 100644 index 00000000000..38f7e466d7d --- /dev/null +++ b/arch/ppc64/boot/div64.S | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Divide a 64-bit unsigned number by a 32-bit unsigned number. | ||
3 | * This routine assumes that the top 32 bits of the dividend are | ||
4 | * non-zero to start with. | ||
5 | * On entry, r3 points to the dividend, which get overwritten with | ||
6 | * the 64-bit quotient, and r4 contains the divisor. | ||
7 | * On exit, r3 contains the remainder. | ||
8 | * | ||
9 | * Copyright (C) 2002 Paul Mackerras, IBM Corp. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | */ | ||
16 | #include <asm/ppc_asm.h> | ||
17 | |||
18 | .globl __div64_32 | ||
19 | __div64_32: | ||
20 | lwz r5,0(r3) # get the dividend into r5/r6 | ||
21 | lwz r6,4(r3) | ||
22 | cmplw r5,r4 | ||
23 | li r7,0 | ||
24 | li r8,0 | ||
25 | blt 1f | ||
26 | divwu r7,r5,r4 # if dividend.hi >= divisor, | ||
27 | mullw r0,r7,r4 # quotient.hi = dividend.hi / divisor | ||
28 | subf. r5,r0,r5 # dividend.hi %= divisor | ||
29 | beq 3f | ||
30 | 1: mr r11,r5 # here dividend.hi != 0 | ||
31 | andis. r0,r5,0xc000 | ||
32 | bne 2f | ||
33 | cntlzw r0,r5 # we are shifting the dividend right | ||
34 | li r10,-1 # to make it < 2^32, and shifting | ||
35 | srw r10,r10,r0 # the divisor right the same amount, | ||
36 | add r9,r4,r10 # rounding up (so the estimate cannot | ||
37 | andc r11,r6,r10 # ever be too large, only too small) | ||
38 | andc r9,r9,r10 | ||
39 | or r11,r5,r11 | ||
40 | rotlw r9,r9,r0 | ||
41 | rotlw r11,r11,r0 | ||
42 | divwu r11,r11,r9 # then we divide the shifted quantities | ||
43 | 2: mullw r10,r11,r4 # to get an estimate of the quotient, | ||
44 | mulhwu r9,r11,r4 # multiply the estimate by the divisor, | ||
45 | subfc r6,r10,r6 # take the product from the divisor, | ||
46 | add r8,r8,r11 # and add the estimate to the accumulated | ||
47 | subfe. r5,r9,r5 # quotient | ||
48 | bne 1b | ||
49 | 3: cmplw r6,r4 | ||
50 | blt 4f | ||
51 | divwu r0,r6,r4 # perform the remaining 32-bit division | ||
52 | mullw r10,r0,r4 # and get the remainder | ||
53 | add r8,r8,r0 | ||
54 | subf r6,r10,r6 | ||
55 | 4: stw r7,0(r3) # return the quotient in *r3 | ||
56 | stw r8,4(r3) | ||
57 | mr r3,r6 # return the remainder in r3 | ||
58 | blr | ||
diff --git a/arch/ppc64/boot/install.sh b/arch/ppc64/boot/install.sh new file mode 100644 index 00000000000..955c5681db6 --- /dev/null +++ b/arch/ppc64/boot/install.sh | |||
@@ -0,0 +1,42 @@ | |||
1 | #!/bin/sh | ||
2 | # | ||
3 | # arch/ppc64/boot/install.sh | ||
4 | # | ||
5 | # This file is subject to the terms and conditions of the GNU General Public | ||
6 | # License. See the file "COPYING" in the main directory of this archive | ||
7 | # for more details. | ||
8 | # | ||
9 | # Copyright (C) 1995 by Linus Torvalds | ||
10 | # | ||
11 | # Blatantly stolen from in arch/i386/boot/install.sh by Dave Hansen | ||
12 | # | ||
13 | # "make install" script for ppc64 architecture | ||
14 | # | ||
15 | # Arguments: | ||
16 | # $1 - kernel version | ||
17 | # $2 - kernel image file | ||
18 | # $3 - kernel map file | ||
19 | # $4 - default install path (blank if root directory) | ||
20 | # $5 - kernel boot file, the zImage | ||
21 | # | ||
22 | |||
23 | # User may have a custom install script | ||
24 | |||
25 | if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi | ||
26 | if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi | ||
27 | |||
28 | # Default install | ||
29 | |||
30 | # this should work for both the pSeries zImage and the iSeries vmlinux.sm | ||
31 | image_name=`basename $5` | ||
32 | |||
33 | if [ -f $4/$image_name ]; then | ||
34 | mv $4/$image_name $4/$image_name.old | ||
35 | fi | ||
36 | |||
37 | if [ -f $4/System.map ]; then | ||
38 | mv $4/System.map $4/System.old | ||
39 | fi | ||
40 | |||
41 | cat $2 > $4/$image_name | ||
42 | cp $3 $4/System.map | ||
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c new file mode 100644 index 00000000000..b0fa86ad8b1 --- /dev/null +++ b/arch/ppc64/boot/main.c | |||
@@ -0,0 +1,331 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * Updates for PPC64 by Todd Inglett, Dave Engebretsen & Peter Bergner. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | #include "ppc32-types.h" | ||
12 | #include "zlib.h" | ||
13 | #include <linux/elf.h> | ||
14 | #include <linux/string.h> | ||
15 | #include <asm/processor.h> | ||
16 | #include <asm/page.h> | ||
17 | #include <asm/bootinfo.h> | ||
18 | |||
19 | extern void *finddevice(const char *); | ||
20 | extern int getprop(void *, const char *, void *, int); | ||
21 | extern void printk(char *fmt, ...); | ||
22 | extern void printf(const char *fmt, ...); | ||
23 | extern int sprintf(char *buf, const char *fmt, ...); | ||
24 | void gunzip(void *, int, unsigned char *, int *); | ||
25 | void *claim(unsigned int, unsigned int, unsigned int); | ||
26 | void flush_cache(void *, unsigned long); | ||
27 | void pause(void); | ||
28 | extern void exit(void); | ||
29 | |||
30 | unsigned long strlen(const char *s); | ||
31 | void *memmove(void *dest, const void *src, unsigned long n); | ||
32 | void *memcpy(void *dest, const void *src, unsigned long n); | ||
33 | |||
34 | /* Value picked to match that used by yaboot */ | ||
35 | #define PROG_START 0x01400000 | ||
36 | #define RAM_END (256<<20) // Fixme: use OF */ | ||
37 | |||
38 | char *avail_ram; | ||
39 | char *begin_avail, *end_avail; | ||
40 | char *avail_high; | ||
41 | unsigned int heap_use; | ||
42 | unsigned int heap_max; | ||
43 | |||
44 | extern char _start[]; | ||
45 | extern char _vmlinux_start[]; | ||
46 | extern char _vmlinux_end[]; | ||
47 | extern char _initrd_start[]; | ||
48 | extern char _initrd_end[]; | ||
49 | extern unsigned long vmlinux_filesize; | ||
50 | extern unsigned long vmlinux_memsize; | ||
51 | |||
52 | struct addr_range { | ||
53 | unsigned long addr; | ||
54 | unsigned long size; | ||
55 | unsigned long memsize; | ||
56 | }; | ||
57 | struct addr_range vmlinux = {0, 0, 0}; | ||
58 | struct addr_range vmlinuz = {0, 0, 0}; | ||
59 | struct addr_range initrd = {0, 0, 0}; | ||
60 | |||
61 | static char scratch[128<<10]; /* 128kB of scratch space for gunzip */ | ||
62 | |||
63 | typedef void (*kernel_entry_t)( unsigned long, | ||
64 | unsigned long, | ||
65 | void *, | ||
66 | void *); | ||
67 | |||
68 | |||
69 | int (*prom)(void *); | ||
70 | |||
71 | void *chosen_handle; | ||
72 | void *stdin; | ||
73 | void *stdout; | ||
74 | void *stderr; | ||
75 | |||
76 | #undef DEBUG | ||
77 | |||
78 | static unsigned long claim_base = PROG_START; | ||
79 | |||
80 | static unsigned long try_claim(unsigned long size) | ||
81 | { | ||
82 | unsigned long addr = 0; | ||
83 | |||
84 | for(; claim_base < RAM_END; claim_base += 0x100000) { | ||
85 | #ifdef DEBUG | ||
86 | printf(" trying: 0x%08lx\n\r", claim_base); | ||
87 | #endif | ||
88 | addr = (unsigned long)claim(claim_base, size, 0); | ||
89 | if ((void *)addr != (void *)-1) | ||
90 | break; | ||
91 | } | ||
92 | if (addr == 0) | ||
93 | return 0; | ||
94 | claim_base = PAGE_ALIGN(claim_base + size); | ||
95 | return addr; | ||
96 | } | ||
97 | |||
98 | void start(unsigned long a1, unsigned long a2, void *promptr) | ||
99 | { | ||
100 | unsigned long i; | ||
101 | kernel_entry_t kernel_entry; | ||
102 | Elf64_Ehdr *elf64; | ||
103 | Elf64_Phdr *elf64ph; | ||
104 | |||
105 | prom = (int (*)(void *)) promptr; | ||
106 | chosen_handle = finddevice("/chosen"); | ||
107 | if (chosen_handle == (void *) -1) | ||
108 | exit(); | ||
109 | if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) | ||
110 | exit(); | ||
111 | stderr = stdout; | ||
112 | if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) | ||
113 | exit(); | ||
114 | |||
115 | printf("\n\rzImage starting: loaded at 0x%x\n\r", (unsigned)_start); | ||
116 | |||
117 | /* | ||
118 | * Now we try to claim some memory for the kernel itself | ||
119 | * our "vmlinux_memsize" is the memory footprint in RAM, _HOWEVER_, what | ||
120 | * our Makefile stuffs in is an image containing all sort of junk including | ||
121 | * an ELF header. We need to do some calculations here to find the right | ||
122 | * size... In practice we add 1Mb, that is enough, but we should really | ||
123 | * consider fixing the Makefile to put a _raw_ kernel in there ! | ||
124 | */ | ||
125 | vmlinux_memsize += 0x100000; | ||
126 | printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize); | ||
127 | vmlinux.addr = try_claim(vmlinux_memsize); | ||
128 | if (vmlinux.addr == 0) { | ||
129 | printf("Can't allocate memory for kernel image !\n\r"); | ||
130 | exit(); | ||
131 | } | ||
132 | vmlinuz.addr = (unsigned long)_vmlinux_start; | ||
133 | vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); | ||
134 | vmlinux.size = PAGE_ALIGN(vmlinux_filesize); | ||
135 | vmlinux.memsize = vmlinux_memsize; | ||
136 | |||
137 | /* | ||
138 | * Now we try to claim memory for the initrd (and copy it there) | ||
139 | */ | ||
140 | initrd.size = (unsigned long)(_initrd_end - _initrd_start); | ||
141 | initrd.memsize = initrd.size; | ||
142 | if ( initrd.size > 0 ) { | ||
143 | printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size); | ||
144 | initrd.addr = try_claim(initrd.size); | ||
145 | if (initrd.addr == 0) { | ||
146 | printf("Can't allocate memory for initial ramdisk !\n\r"); | ||
147 | exit(); | ||
148 | } | ||
149 | a1 = initrd.addr; | ||
150 | a2 = initrd.size; | ||
151 | printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r", | ||
152 | initrd.addr, (unsigned long)_initrd_start, initrd.size); | ||
153 | memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size); | ||
154 | printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr)); | ||
155 | } | ||
156 | |||
157 | /* Eventually gunzip the kernel */ | ||
158 | if (*(unsigned short *)vmlinuz.addr == 0x1f8b) { | ||
159 | int len; | ||
160 | avail_ram = scratch; | ||
161 | begin_avail = avail_high = avail_ram; | ||
162 | end_avail = scratch + sizeof(scratch); | ||
163 | printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...", | ||
164 | vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size); | ||
165 | len = vmlinuz.size; | ||
166 | gunzip((void *)vmlinux.addr, vmlinux.size, | ||
167 | (unsigned char *)vmlinuz.addr, &len); | ||
168 | printf("done 0x%lx bytes\n\r", len); | ||
169 | printf("0x%x bytes of heap consumed, max in use 0x%x\n\r", | ||
170 | (unsigned)(avail_high - begin_avail), heap_max); | ||
171 | } else { | ||
172 | memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size); | ||
173 | } | ||
174 | |||
175 | /* Skip over the ELF header */ | ||
176 | elf64 = (Elf64_Ehdr *)vmlinux.addr; | ||
177 | if ( elf64->e_ident[EI_MAG0] != ELFMAG0 || | ||
178 | elf64->e_ident[EI_MAG1] != ELFMAG1 || | ||
179 | elf64->e_ident[EI_MAG2] != ELFMAG2 || | ||
180 | elf64->e_ident[EI_MAG3] != ELFMAG3 || | ||
181 | elf64->e_ident[EI_CLASS] != ELFCLASS64 || | ||
182 | elf64->e_ident[EI_DATA] != ELFDATA2MSB || | ||
183 | elf64->e_type != ET_EXEC || | ||
184 | elf64->e_machine != EM_PPC64 ) | ||
185 | { | ||
186 | printf("Error: not a valid PPC64 ELF file!\n\r"); | ||
187 | exit(); | ||
188 | } | ||
189 | |||
190 | elf64ph = (Elf64_Phdr *)((unsigned long)elf64 + | ||
191 | (unsigned long)elf64->e_phoff); | ||
192 | for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) { | ||
193 | if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0) | ||
194 | break; | ||
195 | } | ||
196 | #ifdef DEBUG | ||
197 | printf("... skipping 0x%lx bytes of ELF header\n\r", | ||
198 | (unsigned long)elf64ph->p_offset); | ||
199 | #endif | ||
200 | vmlinux.addr += (unsigned long)elf64ph->p_offset; | ||
201 | vmlinux.size -= (unsigned long)elf64ph->p_offset; | ||
202 | |||
203 | flush_cache((void *)vmlinux.addr, vmlinux.size); | ||
204 | |||
205 | if (a1) | ||
206 | printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr)); | ||
207 | |||
208 | kernel_entry = (kernel_entry_t)vmlinux.addr; | ||
209 | #ifdef DEBUG | ||
210 | printf( "kernel:\n\r" | ||
211 | " entry addr = 0x%lx\n\r" | ||
212 | " a1 = 0x%lx,\n\r" | ||
213 | " a2 = 0x%lx,\n\r" | ||
214 | " prom = 0x%lx,\n\r" | ||
215 | " bi_recs = 0x%lx,\n\r", | ||
216 | (unsigned long)kernel_entry, a1, a2, | ||
217 | (unsigned long)prom, NULL); | ||
218 | #endif | ||
219 | |||
220 | kernel_entry( a1, a2, prom, NULL ); | ||
221 | |||
222 | printf("Error: Linux kernel returned to zImage bootloader!\n\r"); | ||
223 | |||
224 | exit(); | ||
225 | } | ||
226 | |||
227 | struct memchunk { | ||
228 | unsigned int size; | ||
229 | unsigned int pad; | ||
230 | struct memchunk *next; | ||
231 | }; | ||
232 | |||
233 | static struct memchunk *freechunks; | ||
234 | |||
235 | void *zalloc(void *x, unsigned items, unsigned size) | ||
236 | { | ||
237 | void *p; | ||
238 | struct memchunk **mpp, *mp; | ||
239 | |||
240 | size *= items; | ||
241 | size = _ALIGN(size, sizeof(struct memchunk)); | ||
242 | heap_use += size; | ||
243 | if (heap_use > heap_max) | ||
244 | heap_max = heap_use; | ||
245 | for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { | ||
246 | if (mp->size == size) { | ||
247 | *mpp = mp->next; | ||
248 | return mp; | ||
249 | } | ||
250 | } | ||
251 | p = avail_ram; | ||
252 | avail_ram += size; | ||
253 | if (avail_ram > avail_high) | ||
254 | avail_high = avail_ram; | ||
255 | if (avail_ram > end_avail) { | ||
256 | printf("oops... out of memory\n\r"); | ||
257 | pause(); | ||
258 | } | ||
259 | return p; | ||
260 | } | ||
261 | |||
262 | void zfree(void *x, void *addr, unsigned nb) | ||
263 | { | ||
264 | struct memchunk *mp = addr; | ||
265 | |||
266 | nb = _ALIGN(nb, sizeof(struct memchunk)); | ||
267 | heap_use -= nb; | ||
268 | if (avail_ram == addr + nb) { | ||
269 | avail_ram = addr; | ||
270 | return; | ||
271 | } | ||
272 | mp->size = nb; | ||
273 | mp->next = freechunks; | ||
274 | freechunks = mp; | ||
275 | } | ||
276 | |||
277 | #define HEAD_CRC 2 | ||
278 | #define EXTRA_FIELD 4 | ||
279 | #define ORIG_NAME 8 | ||
280 | #define COMMENT 0x10 | ||
281 | #define RESERVED 0xe0 | ||
282 | |||
283 | #define DEFLATED 8 | ||
284 | |||
285 | void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) | ||
286 | { | ||
287 | z_stream s; | ||
288 | int r, i, flags; | ||
289 | |||
290 | /* skip header */ | ||
291 | i = 10; | ||
292 | flags = src[3]; | ||
293 | if (src[2] != DEFLATED || (flags & RESERVED) != 0) { | ||
294 | printf("bad gzipped data\n\r"); | ||
295 | exit(); | ||
296 | } | ||
297 | if ((flags & EXTRA_FIELD) != 0) | ||
298 | i = 12 + src[10] + (src[11] << 8); | ||
299 | if ((flags & ORIG_NAME) != 0) | ||
300 | while (src[i++] != 0) | ||
301 | ; | ||
302 | if ((flags & COMMENT) != 0) | ||
303 | while (src[i++] != 0) | ||
304 | ; | ||
305 | if ((flags & HEAD_CRC) != 0) | ||
306 | i += 2; | ||
307 | if (i >= *lenp) { | ||
308 | printf("gunzip: ran out of data in header\n\r"); | ||
309 | exit(); | ||
310 | } | ||
311 | |||
312 | s.zalloc = zalloc; | ||
313 | s.zfree = zfree; | ||
314 | r = inflateInit2(&s, -MAX_WBITS); | ||
315 | if (r != Z_OK) { | ||
316 | printf("inflateInit2 returned %d\n\r", r); | ||
317 | exit(); | ||
318 | } | ||
319 | s.next_in = src + i; | ||
320 | s.avail_in = *lenp - i; | ||
321 | s.next_out = dst; | ||
322 | s.avail_out = dstlen; | ||
323 | r = inflate(&s, Z_FINISH); | ||
324 | if (r != Z_OK && r != Z_STREAM_END) { | ||
325 | printf("inflate returned %d msg: %s\n\r", r, s.msg); | ||
326 | exit(); | ||
327 | } | ||
328 | *lenp = s.next_out - (unsigned char *) dst; | ||
329 | inflateEnd(&s); | ||
330 | } | ||
331 | |||
diff --git a/arch/ppc64/boot/mknote.c b/arch/ppc64/boot/mknote.c new file mode 100644 index 00000000000..120cc1d8973 --- /dev/null +++ b/arch/ppc64/boot/mknote.c | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Copyright (C) Cort Dougan 1999. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * Generate a note section as per the CHRP specification. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <stdio.h> | ||
14 | |||
15 | #define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); | ||
16 | |||
17 | int main(void) | ||
18 | { | ||
19 | /* header */ | ||
20 | /* namesz */ | ||
21 | PL(strlen("PowerPC")+1); | ||
22 | /* descrsz */ | ||
23 | PL(6*4); | ||
24 | /* type */ | ||
25 | PL(0x1275); | ||
26 | /* name */ | ||
27 | printf("PowerPC"); printf("%c", 0); | ||
28 | |||
29 | /* descriptor */ | ||
30 | /* real-mode */ | ||
31 | PL(0xffffffff); | ||
32 | /* real-base */ | ||
33 | PL(0x00c00000); | ||
34 | /* real-size */ | ||
35 | PL(0xffffffff); | ||
36 | /* virt-base */ | ||
37 | PL(0xffffffff); | ||
38 | /* virt-size */ | ||
39 | PL(0xffffffff); | ||
40 | /* load-base */ | ||
41 | PL(0x4000); | ||
42 | return 0; | ||
43 | } | ||
diff --git a/arch/ppc64/boot/piggyback.c b/arch/ppc64/boot/piggyback.c new file mode 100644 index 00000000000..235c7a87269 --- /dev/null +++ b/arch/ppc64/boot/piggyback.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * Copyright 2001 IBM Corp | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <stdio.h> | ||
10 | #include <unistd.h> | ||
11 | #include <string.h> | ||
12 | |||
13 | extern long ce_exec_config[]; | ||
14 | |||
15 | int main(int argc, char *argv[]) | ||
16 | { | ||
17 | int i, cnt, pos, len; | ||
18 | unsigned int cksum, val; | ||
19 | unsigned char *lp; | ||
20 | unsigned char buf[8192]; | ||
21 | char *varname; | ||
22 | if (argc != 2) | ||
23 | { | ||
24 | fprintf(stderr, "usage: %s name <in-file >out-file\n", | ||
25 | argv[0]); | ||
26 | exit(1); | ||
27 | } | ||
28 | |||
29 | varname = strrchr(argv[1], '/'); | ||
30 | if (varname) | ||
31 | varname++; | ||
32 | else | ||
33 | varname = argv[1]; | ||
34 | |||
35 | fprintf(stdout, "#\n"); | ||
36 | fprintf(stdout, "# Miscellaneous data structures:\n"); | ||
37 | fprintf(stdout, "# WARNING - this file is automatically generated!\n"); | ||
38 | fprintf(stdout, "#\n"); | ||
39 | fprintf(stdout, "\n"); | ||
40 | fprintf(stdout, "\t.data\n"); | ||
41 | fprintf(stdout, "\t.globl %s_data\n", varname); | ||
42 | fprintf(stdout, "%s_data:\n", varname); | ||
43 | pos = 0; | ||
44 | cksum = 0; | ||
45 | while ((len = read(0, buf, sizeof(buf))) > 0) | ||
46 | { | ||
47 | cnt = 0; | ||
48 | lp = (unsigned char *)buf; | ||
49 | len = (len + 3) & ~3; /* Round up to longwords */ | ||
50 | for (i = 0; i < len; i += 4) | ||
51 | { | ||
52 | if (cnt == 0) | ||
53 | { | ||
54 | fprintf(stdout, "\t.long\t"); | ||
55 | } | ||
56 | fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); | ||
57 | val = *(unsigned long *)lp; | ||
58 | cksum ^= val; | ||
59 | lp += 4; | ||
60 | if (++cnt == 4) | ||
61 | { | ||
62 | cnt = 0; | ||
63 | fprintf(stdout, " # %x \n", pos+i-12); | ||
64 | fflush(stdout); | ||
65 | } else | ||
66 | { | ||
67 | fprintf(stdout, ","); | ||
68 | } | ||
69 | } | ||
70 | if (cnt) | ||
71 | { | ||
72 | fprintf(stdout, "0\n"); | ||
73 | } | ||
74 | pos += len; | ||
75 | } | ||
76 | fprintf(stdout, "\t.globl %s_len\n", varname); | ||
77 | fprintf(stdout, "%s_len:\t.long\t0x%x\n", varname, pos); | ||
78 | fflush(stdout); | ||
79 | fclose(stdout); | ||
80 | fprintf(stderr, "cksum = %x\n", cksum); | ||
81 | exit(0); | ||
82 | } | ||
83 | |||
diff --git a/arch/ppc64/boot/ppc32-types.h b/arch/ppc64/boot/ppc32-types.h new file mode 100644 index 00000000000..f7b8884f8f7 --- /dev/null +++ b/arch/ppc64/boot/ppc32-types.h | |||
@@ -0,0 +1,36 @@ | |||
1 | #ifndef _PPC64_TYPES_H | ||
2 | #define _PPC64_TYPES_H | ||
3 | |||
4 | typedef __signed__ char __s8; | ||
5 | typedef unsigned char __u8; | ||
6 | |||
7 | typedef __signed__ short __s16; | ||
8 | typedef unsigned short __u16; | ||
9 | |||
10 | typedef __signed__ int __s32; | ||
11 | typedef unsigned int __u32; | ||
12 | |||
13 | typedef __signed__ long long __s64; | ||
14 | typedef unsigned long long __u64; | ||
15 | |||
16 | typedef signed char s8; | ||
17 | typedef unsigned char u8; | ||
18 | |||
19 | typedef signed short s16; | ||
20 | typedef unsigned short u16; | ||
21 | |||
22 | typedef signed int s32; | ||
23 | typedef unsigned int u32; | ||
24 | |||
25 | typedef signed long long s64; | ||
26 | typedef unsigned long long u64; | ||
27 | |||
28 | typedef struct { | ||
29 | __u32 u[4]; | ||
30 | } __attribute((aligned(16))) __vector128; | ||
31 | |||
32 | #define BITS_PER_LONG 32 | ||
33 | |||
34 | typedef __vector128 vector128; | ||
35 | |||
36 | #endif /* _PPC64_TYPES_H */ | ||
diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c new file mode 100644 index 00000000000..7b607d1862c --- /dev/null +++ b/arch/ppc64/boot/prom.c | |||
@@ -0,0 +1,637 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <stdarg.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/ctype.h> | ||
13 | |||
14 | int (*prom)(void *); | ||
15 | |||
16 | void *chosen_handle; | ||
17 | void *stdin; | ||
18 | void *stdout; | ||
19 | void *stderr; | ||
20 | |||
21 | void exit(void); | ||
22 | void *finddevice(const char *name); | ||
23 | int getprop(void *phandle, const char *name, void *buf, int buflen); | ||
24 | void chrpboot(int a1, int a2, void *prom); /* in main.c */ | ||
25 | |||
26 | void printk(char *fmt, ...); | ||
27 | |||
28 | /* there is no convenient header to get this from... -- paulus */ | ||
29 | extern unsigned long strlen(const char *); | ||
30 | |||
31 | int | ||
32 | write(void *handle, void *ptr, int nb) | ||
33 | { | ||
34 | struct prom_args { | ||
35 | char *service; | ||
36 | int nargs; | ||
37 | int nret; | ||
38 | void *ihandle; | ||
39 | void *addr; | ||
40 | int len; | ||
41 | int actual; | ||
42 | } args; | ||
43 | |||
44 | args.service = "write"; | ||
45 | args.nargs = 3; | ||
46 | args.nret = 1; | ||
47 | args.ihandle = handle; | ||
48 | args.addr = ptr; | ||
49 | args.len = nb; | ||
50 | args.actual = -1; | ||
51 | (*prom)(&args); | ||
52 | return args.actual; | ||
53 | } | ||
54 | |||
55 | int | ||
56 | read(void *handle, void *ptr, int nb) | ||
57 | { | ||
58 | struct prom_args { | ||
59 | char *service; | ||
60 | int nargs; | ||
61 | int nret; | ||
62 | void *ihandle; | ||
63 | void *addr; | ||
64 | int len; | ||
65 | int actual; | ||
66 | } args; | ||
67 | |||
68 | args.service = "read"; | ||
69 | args.nargs = 3; | ||
70 | args.nret = 1; | ||
71 | args.ihandle = handle; | ||
72 | args.addr = ptr; | ||
73 | args.len = nb; | ||
74 | args.actual = -1; | ||
75 | (*prom)(&args); | ||
76 | return args.actual; | ||
77 | } | ||
78 | |||
79 | void | ||
80 | exit() | ||
81 | { | ||
82 | struct prom_args { | ||
83 | char *service; | ||
84 | } args; | ||
85 | |||
86 | for (;;) { | ||
87 | args.service = "exit"; | ||
88 | (*prom)(&args); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | void | ||
93 | pause(void) | ||
94 | { | ||
95 | struct prom_args { | ||
96 | char *service; | ||
97 | } args; | ||
98 | |||
99 | args.service = "enter"; | ||
100 | (*prom)(&args); | ||
101 | } | ||
102 | |||
103 | void * | ||
104 | finddevice(const char *name) | ||
105 | { | ||
106 | struct prom_args { | ||
107 | char *service; | ||
108 | int nargs; | ||
109 | int nret; | ||
110 | const char *devspec; | ||
111 | void *phandle; | ||
112 | } args; | ||
113 | |||
114 | args.service = "finddevice"; | ||
115 | args.nargs = 1; | ||
116 | args.nret = 1; | ||
117 | args.devspec = name; | ||
118 | args.phandle = (void *) -1; | ||
119 | (*prom)(&args); | ||
120 | return args.phandle; | ||
121 | } | ||
122 | |||
123 | void * | ||
124 | claim(unsigned long virt, unsigned long size, unsigned long align) | ||
125 | { | ||
126 | struct prom_args { | ||
127 | char *service; | ||
128 | int nargs; | ||
129 | int nret; | ||
130 | unsigned int virt; | ||
131 | unsigned int size; | ||
132 | unsigned int align; | ||
133 | void *ret; | ||
134 | } args; | ||
135 | |||
136 | args.service = "claim"; | ||
137 | args.nargs = 3; | ||
138 | args.nret = 1; | ||
139 | args.virt = virt; | ||
140 | args.size = size; | ||
141 | args.align = align; | ||
142 | (*prom)(&args); | ||
143 | return args.ret; | ||
144 | } | ||
145 | |||
146 | int | ||
147 | getprop(void *phandle, const char *name, void *buf, int buflen) | ||
148 | { | ||
149 | struct prom_args { | ||
150 | char *service; | ||
151 | int nargs; | ||
152 | int nret; | ||
153 | void *phandle; | ||
154 | const char *name; | ||
155 | void *buf; | ||
156 | int buflen; | ||
157 | int size; | ||
158 | } args; | ||
159 | |||
160 | args.service = "getprop"; | ||
161 | args.nargs = 4; | ||
162 | args.nret = 1; | ||
163 | args.phandle = phandle; | ||
164 | args.name = name; | ||
165 | args.buf = buf; | ||
166 | args.buflen = buflen; | ||
167 | args.size = -1; | ||
168 | (*prom)(&args); | ||
169 | return args.size; | ||
170 | } | ||
171 | |||
172 | int | ||
173 | putc(int c, void *f) | ||
174 | { | ||
175 | char ch = c; | ||
176 | |||
177 | if (c == '\n') | ||
178 | putc('\r', f); | ||
179 | return write(f, &ch, 1) == 1? c: -1; | ||
180 | } | ||
181 | |||
182 | int | ||
183 | putchar(int c) | ||
184 | { | ||
185 | return putc(c, stdout); | ||
186 | } | ||
187 | |||
188 | int | ||
189 | fputs(char *str, void *f) | ||
190 | { | ||
191 | int n = strlen(str); | ||
192 | |||
193 | return write(f, str, n) == n? 0: -1; | ||
194 | } | ||
195 | |||
196 | int | ||
197 | readchar(void) | ||
198 | { | ||
199 | char ch; | ||
200 | |||
201 | for (;;) { | ||
202 | switch (read(stdin, &ch, 1)) { | ||
203 | case 1: | ||
204 | return ch; | ||
205 | case -1: | ||
206 | printk("read(stdin) returned -1\r\n"); | ||
207 | return -1; | ||
208 | } | ||
209 | } | ||
210 | } | ||
211 | |||
212 | static char line[256]; | ||
213 | static char *lineptr; | ||
214 | static int lineleft; | ||
215 | |||
216 | int | ||
217 | getchar(void) | ||
218 | { | ||
219 | int c; | ||
220 | |||
221 | if (lineleft == 0) { | ||
222 | lineptr = line; | ||
223 | for (;;) { | ||
224 | c = readchar(); | ||
225 | if (c == -1 || c == 4) | ||
226 | break; | ||
227 | if (c == '\r' || c == '\n') { | ||
228 | *lineptr++ = '\n'; | ||
229 | putchar('\n'); | ||
230 | break; | ||
231 | } | ||
232 | switch (c) { | ||
233 | case 0177: | ||
234 | case '\b': | ||
235 | if (lineptr > line) { | ||
236 | putchar('\b'); | ||
237 | putchar(' '); | ||
238 | putchar('\b'); | ||
239 | --lineptr; | ||
240 | } | ||
241 | break; | ||
242 | case 'U' & 0x1F: | ||
243 | while (lineptr > line) { | ||
244 | putchar('\b'); | ||
245 | putchar(' '); | ||
246 | putchar('\b'); | ||
247 | --lineptr; | ||
248 | } | ||
249 | break; | ||
250 | default: | ||
251 | if (lineptr >= &line[sizeof(line) - 1]) | ||
252 | putchar('\a'); | ||
253 | else { | ||
254 | putchar(c); | ||
255 | *lineptr++ = c; | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | lineleft = lineptr - line; | ||
260 | lineptr = line; | ||
261 | } | ||
262 | if (lineleft == 0) | ||
263 | return -1; | ||
264 | --lineleft; | ||
265 | return *lineptr++; | ||
266 | } | ||
267 | |||
268 | |||
269 | |||
270 | /* String functions lifted from lib/vsprintf.c and lib/ctype.c */ | ||
271 | unsigned char _ctype[] = { | ||
272 | _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ | ||
273 | _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ | ||
274 | _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ | ||
275 | _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ | ||
276 | _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ | ||
277 | _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ | ||
278 | _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ | ||
279 | _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ | ||
280 | _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ | ||
281 | _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ | ||
282 | _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ | ||
283 | _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ | ||
284 | _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ | ||
285 | _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ | ||
286 | _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ | ||
287 | _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ | ||
288 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ | ||
289 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ | ||
290 | _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ | ||
291 | _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ | ||
292 | _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ | ||
293 | _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ | ||
294 | _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ | ||
295 | _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ | ||
296 | |||
297 | size_t strnlen(const char * s, size_t count) | ||
298 | { | ||
299 | const char *sc; | ||
300 | |||
301 | for (sc = s; count-- && *sc != '\0'; ++sc) | ||
302 | /* nothing */; | ||
303 | return sc - s; | ||
304 | } | ||
305 | |||
306 | unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) | ||
307 | { | ||
308 | unsigned long result = 0,value; | ||
309 | |||
310 | if (!base) { | ||
311 | base = 10; | ||
312 | if (*cp == '0') { | ||
313 | base = 8; | ||
314 | cp++; | ||
315 | if ((*cp == 'x') && isxdigit(cp[1])) { | ||
316 | cp++; | ||
317 | base = 16; | ||
318 | } | ||
319 | } | ||
320 | } | ||
321 | while (isxdigit(*cp) && | ||
322 | (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { | ||
323 | result = result*base + value; | ||
324 | cp++; | ||
325 | } | ||
326 | if (endp) | ||
327 | *endp = (char *)cp; | ||
328 | return result; | ||
329 | } | ||
330 | |||
331 | long simple_strtol(const char *cp,char **endp,unsigned int base) | ||
332 | { | ||
333 | if(*cp=='-') | ||
334 | return -simple_strtoul(cp+1,endp,base); | ||
335 | return simple_strtoul(cp,endp,base); | ||
336 | } | ||
337 | |||
338 | static int skip_atoi(const char **s) | ||
339 | { | ||
340 | int i=0; | ||
341 | |||
342 | while (isdigit(**s)) | ||
343 | i = i*10 + *((*s)++) - '0'; | ||
344 | return i; | ||
345 | } | ||
346 | |||
347 | #define ZEROPAD 1 /* pad with zero */ | ||
348 | #define SIGN 2 /* unsigned/signed long */ | ||
349 | #define PLUS 4 /* show plus */ | ||
350 | #define SPACE 8 /* space if plus */ | ||
351 | #define LEFT 16 /* left justified */ | ||
352 | #define SPECIAL 32 /* 0x */ | ||
353 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ | ||
354 | |||
355 | static char * number(char * str, long num, int base, int size, int precision, int type) | ||
356 | { | ||
357 | char c,sign,tmp[66]; | ||
358 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; | ||
359 | int i; | ||
360 | |||
361 | if (type & LARGE) | ||
362 | digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
363 | if (type & LEFT) | ||
364 | type &= ~ZEROPAD; | ||
365 | if (base < 2 || base > 36) | ||
366 | return 0; | ||
367 | c = (type & ZEROPAD) ? '0' : ' '; | ||
368 | sign = 0; | ||
369 | if (type & SIGN) { | ||
370 | if (num < 0) { | ||
371 | sign = '-'; | ||
372 | num = -num; | ||
373 | size--; | ||
374 | } else if (type & PLUS) { | ||
375 | sign = '+'; | ||
376 | size--; | ||
377 | } else if (type & SPACE) { | ||
378 | sign = ' '; | ||
379 | size--; | ||
380 | } | ||
381 | } | ||
382 | if (type & SPECIAL) { | ||
383 | if (base == 16) | ||
384 | size -= 2; | ||
385 | else if (base == 8) | ||
386 | size--; | ||
387 | } | ||
388 | i = 0; | ||
389 | if (num == 0) | ||
390 | tmp[i++]='0'; | ||
391 | else while (num != 0) { | ||
392 | tmp[i++] = digits[num % base]; | ||
393 | num /= base; | ||
394 | } | ||
395 | if (i > precision) | ||
396 | precision = i; | ||
397 | size -= precision; | ||
398 | if (!(type&(ZEROPAD+LEFT))) | ||
399 | while(size-->0) | ||
400 | *str++ = ' '; | ||
401 | if (sign) | ||
402 | *str++ = sign; | ||
403 | if (type & SPECIAL) { | ||
404 | if (base==8) | ||
405 | *str++ = '0'; | ||
406 | else if (base==16) { | ||
407 | *str++ = '0'; | ||
408 | *str++ = digits[33]; | ||
409 | } | ||
410 | } | ||
411 | if (!(type & LEFT)) | ||
412 | while (size-- > 0) | ||
413 | *str++ = c; | ||
414 | while (i < precision--) | ||
415 | *str++ = '0'; | ||
416 | while (i-- > 0) | ||
417 | *str++ = tmp[i]; | ||
418 | while (size-- > 0) | ||
419 | *str++ = ' '; | ||
420 | return str; | ||
421 | } | ||
422 | |||
423 | /* Forward decl. needed for IP address printing stuff... */ | ||
424 | int sprintf(char * buf, const char *fmt, ...); | ||
425 | |||
426 | int vsprintf(char *buf, const char *fmt, va_list args) | ||
427 | { | ||
428 | int len; | ||
429 | unsigned long num; | ||
430 | int i, base; | ||
431 | char * str; | ||
432 | const char *s; | ||
433 | |||
434 | int flags; /* flags to number() */ | ||
435 | |||
436 | int field_width; /* width of output field */ | ||
437 | int precision; /* min. # of digits for integers; max | ||
438 | number of chars for from string */ | ||
439 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ | ||
440 | /* 'z' support added 23/7/1999 S.H. */ | ||
441 | /* 'z' changed to 'Z' --davidm 1/25/99 */ | ||
442 | |||
443 | |||
444 | for (str=buf ; *fmt ; ++fmt) { | ||
445 | if (*fmt != '%') { | ||
446 | *str++ = *fmt; | ||
447 | continue; | ||
448 | } | ||
449 | |||
450 | /* process flags */ | ||
451 | flags = 0; | ||
452 | repeat: | ||
453 | ++fmt; /* this also skips first '%' */ | ||
454 | switch (*fmt) { | ||
455 | case '-': flags |= LEFT; goto repeat; | ||
456 | case '+': flags |= PLUS; goto repeat; | ||
457 | case ' ': flags |= SPACE; goto repeat; | ||
458 | case '#': flags |= SPECIAL; goto repeat; | ||
459 | case '0': flags |= ZEROPAD; goto repeat; | ||
460 | } | ||
461 | |||
462 | /* get field width */ | ||
463 | field_width = -1; | ||
464 | if (isdigit(*fmt)) | ||
465 | field_width = skip_atoi(&fmt); | ||
466 | else if (*fmt == '*') { | ||
467 | ++fmt; | ||
468 | /* it's the next argument */ | ||
469 | field_width = va_arg(args, int); | ||
470 | if (field_width < 0) { | ||
471 | field_width = -field_width; | ||
472 | flags |= LEFT; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | /* get the precision */ | ||
477 | precision = -1; | ||
478 | if (*fmt == '.') { | ||
479 | ++fmt; | ||
480 | if (isdigit(*fmt)) | ||
481 | precision = skip_atoi(&fmt); | ||
482 | else if (*fmt == '*') { | ||
483 | ++fmt; | ||
484 | /* it's the next argument */ | ||
485 | precision = va_arg(args, int); | ||
486 | } | ||
487 | if (precision < 0) | ||
488 | precision = 0; | ||
489 | } | ||
490 | |||
491 | /* get the conversion qualifier */ | ||
492 | qualifier = -1; | ||
493 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { | ||
494 | qualifier = *fmt; | ||
495 | ++fmt; | ||
496 | } | ||
497 | |||
498 | /* default base */ | ||
499 | base = 10; | ||
500 | |||
501 | switch (*fmt) { | ||
502 | case 'c': | ||
503 | if (!(flags & LEFT)) | ||
504 | while (--field_width > 0) | ||
505 | *str++ = ' '; | ||
506 | *str++ = (unsigned char) va_arg(args, int); | ||
507 | while (--field_width > 0) | ||
508 | *str++ = ' '; | ||
509 | continue; | ||
510 | |||
511 | case 's': | ||
512 | s = va_arg(args, char *); | ||
513 | if (!s) | ||
514 | s = "<NULL>"; | ||
515 | |||
516 | len = strnlen(s, precision); | ||
517 | |||
518 | if (!(flags & LEFT)) | ||
519 | while (len < field_width--) | ||
520 | *str++ = ' '; | ||
521 | for (i = 0; i < len; ++i) | ||
522 | *str++ = *s++; | ||
523 | while (len < field_width--) | ||
524 | *str++ = ' '; | ||
525 | continue; | ||
526 | |||
527 | case 'p': | ||
528 | if (field_width == -1) { | ||
529 | field_width = 2*sizeof(void *); | ||
530 | flags |= ZEROPAD; | ||
531 | } | ||
532 | str = number(str, | ||
533 | (unsigned long) va_arg(args, void *), 16, | ||
534 | field_width, precision, flags); | ||
535 | continue; | ||
536 | |||
537 | |||
538 | case 'n': | ||
539 | if (qualifier == 'l') { | ||
540 | long * ip = va_arg(args, long *); | ||
541 | *ip = (str - buf); | ||
542 | } else if (qualifier == 'Z') { | ||
543 | size_t * ip = va_arg(args, size_t *); | ||
544 | *ip = (str - buf); | ||
545 | } else { | ||
546 | int * ip = va_arg(args, int *); | ||
547 | *ip = (str - buf); | ||
548 | } | ||
549 | continue; | ||
550 | |||
551 | case '%': | ||
552 | *str++ = '%'; | ||
553 | continue; | ||
554 | |||
555 | /* integer number formats - set up the flags and "break" */ | ||
556 | case 'o': | ||
557 | base = 8; | ||
558 | break; | ||
559 | |||
560 | case 'X': | ||
561 | flags |= LARGE; | ||
562 | case 'x': | ||
563 | base = 16; | ||
564 | break; | ||
565 | |||
566 | case 'd': | ||
567 | case 'i': | ||
568 | flags |= SIGN; | ||
569 | case 'u': | ||
570 | break; | ||
571 | |||
572 | default: | ||
573 | *str++ = '%'; | ||
574 | if (*fmt) | ||
575 | *str++ = *fmt; | ||
576 | else | ||
577 | --fmt; | ||
578 | continue; | ||
579 | } | ||
580 | if (qualifier == 'l') { | ||
581 | num = va_arg(args, unsigned long); | ||
582 | if (flags & SIGN) | ||
583 | num = (signed long) num; | ||
584 | } else if (qualifier == 'Z') { | ||
585 | num = va_arg(args, size_t); | ||
586 | } else if (qualifier == 'h') { | ||
587 | num = (unsigned short) va_arg(args, int); | ||
588 | if (flags & SIGN) | ||
589 | num = (signed short) num; | ||
590 | } else { | ||
591 | num = va_arg(args, unsigned int); | ||
592 | if (flags & SIGN) | ||
593 | num = (signed int) num; | ||
594 | } | ||
595 | str = number(str, num, base, field_width, precision, flags); | ||
596 | } | ||
597 | *str = '\0'; | ||
598 | return str-buf; | ||
599 | } | ||
600 | |||
601 | int sprintf(char * buf, const char *fmt, ...) | ||
602 | { | ||
603 | va_list args; | ||
604 | int i; | ||
605 | |||
606 | va_start(args, fmt); | ||
607 | i=vsprintf(buf,fmt,args); | ||
608 | va_end(args); | ||
609 | return i; | ||
610 | } | ||
611 | |||
612 | static char sprint_buf[1024]; | ||
613 | |||
614 | void | ||
615 | printk(char *fmt, ...) | ||
616 | { | ||
617 | va_list args; | ||
618 | int n; | ||
619 | |||
620 | va_start(args, fmt); | ||
621 | n = vsprintf(sprint_buf, fmt, args); | ||
622 | va_end(args); | ||
623 | write(stdout, sprint_buf, n); | ||
624 | } | ||
625 | |||
626 | int | ||
627 | printf(char *fmt, ...) | ||
628 | { | ||
629 | va_list args; | ||
630 | int n; | ||
631 | |||
632 | va_start(args, fmt); | ||
633 | n = vsprintf(sprint_buf, fmt, args); | ||
634 | va_end(args); | ||
635 | write(stdout, sprint_buf, n); | ||
636 | return n; | ||
637 | } | ||
diff --git a/arch/ppc64/boot/start.c b/arch/ppc64/boot/start.c new file mode 100644 index 00000000000..ea247e79b55 --- /dev/null +++ b/arch/ppc64/boot/start.c | |||
@@ -0,0 +1,654 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <stdarg.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/ctype.h> | ||
13 | |||
14 | #include <asm/div64.h> | ||
15 | |||
16 | int (*prom)(void *); | ||
17 | |||
18 | void *chosen_handle; | ||
19 | void *stdin; | ||
20 | void *stdout; | ||
21 | void *stderr; | ||
22 | |||
23 | void exit(void); | ||
24 | void *finddevice(const char *name); | ||
25 | int getprop(void *phandle, const char *name, void *buf, int buflen); | ||
26 | void chrpboot(int a1, int a2, void *prom); /* in main.c */ | ||
27 | |||
28 | void printk(char *fmt, ...); | ||
29 | |||
30 | void | ||
31 | start(int a1, int a2, void *promptr) | ||
32 | { | ||
33 | prom = (int (*)(void *)) promptr; | ||
34 | chosen_handle = finddevice("/chosen"); | ||
35 | if (chosen_handle == (void *) -1) | ||
36 | exit(); | ||
37 | if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) | ||
38 | exit(); | ||
39 | stderr = stdout; | ||
40 | if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) | ||
41 | exit(); | ||
42 | |||
43 | chrpboot(a1, a2, promptr); | ||
44 | for (;;) | ||
45 | exit(); | ||
46 | } | ||
47 | |||
48 | int | ||
49 | write(void *handle, void *ptr, int nb) | ||
50 | { | ||
51 | struct prom_args { | ||
52 | char *service; | ||
53 | int nargs; | ||
54 | int nret; | ||
55 | void *ihandle; | ||
56 | void *addr; | ||
57 | int len; | ||
58 | int actual; | ||
59 | } args; | ||
60 | |||
61 | args.service = "write"; | ||
62 | args.nargs = 3; | ||
63 | args.nret = 1; | ||
64 | args.ihandle = handle; | ||
65 | args.addr = ptr; | ||
66 | args.len = nb; | ||
67 | args.actual = -1; | ||
68 | (*prom)(&args); | ||
69 | return args.actual; | ||
70 | } | ||
71 | |||
72 | int | ||
73 | read(void *handle, void *ptr, int nb) | ||
74 | { | ||
75 | struct prom_args { | ||
76 | char *service; | ||
77 | int nargs; | ||
78 | int nret; | ||
79 | void *ihandle; | ||
80 | void *addr; | ||
81 | int len; | ||
82 | int actual; | ||
83 | } args; | ||
84 | |||
85 | args.service = "read"; | ||
86 | args.nargs = 3; | ||
87 | args.nret = 1; | ||
88 | args.ihandle = handle; | ||
89 | args.addr = ptr; | ||
90 | args.len = nb; | ||
91 | args.actual = -1; | ||
92 | (*prom)(&args); | ||
93 | return args.actual; | ||
94 | } | ||
95 | |||
96 | void | ||
97 | exit() | ||
98 | { | ||
99 | struct prom_args { | ||
100 | char *service; | ||
101 | } args; | ||
102 | |||
103 | for (;;) { | ||
104 | args.service = "exit"; | ||
105 | (*prom)(&args); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | void | ||
110 | pause(void) | ||
111 | { | ||
112 | struct prom_args { | ||
113 | char *service; | ||
114 | } args; | ||
115 | |||
116 | args.service = "enter"; | ||
117 | (*prom)(&args); | ||
118 | } | ||
119 | |||
120 | void * | ||
121 | finddevice(const char *name) | ||
122 | { | ||
123 | struct prom_args { | ||
124 | char *service; | ||
125 | int nargs; | ||
126 | int nret; | ||
127 | const char *devspec; | ||
128 | void *phandle; | ||
129 | } args; | ||
130 | |||
131 | args.service = "finddevice"; | ||
132 | args.nargs = 1; | ||
133 | args.nret = 1; | ||
134 | args.devspec = name; | ||
135 | args.phandle = (void *) -1; | ||
136 | (*prom)(&args); | ||
137 | return args.phandle; | ||
138 | } | ||
139 | |||
140 | void * | ||
141 | claim(unsigned long virt, unsigned long size, unsigned long align) | ||
142 | { | ||
143 | struct prom_args { | ||
144 | char *service; | ||
145 | int nargs; | ||
146 | int nret; | ||
147 | unsigned int virt; | ||
148 | unsigned int size; | ||
149 | unsigned int align; | ||
150 | void *ret; | ||
151 | } args; | ||
152 | |||
153 | args.service = "claim"; | ||
154 | args.nargs = 3; | ||
155 | args.nret = 1; | ||
156 | args.virt = virt; | ||
157 | args.size = size; | ||
158 | args.align = align; | ||
159 | (*prom)(&args); | ||
160 | return args.ret; | ||
161 | } | ||
162 | |||
163 | int | ||
164 | getprop(void *phandle, const char *name, void *buf, int buflen) | ||
165 | { | ||
166 | struct prom_args { | ||
167 | char *service; | ||
168 | int nargs; | ||
169 | int nret; | ||
170 | void *phandle; | ||
171 | const char *name; | ||
172 | void *buf; | ||
173 | int buflen; | ||
174 | int size; | ||
175 | } args; | ||
176 | |||
177 | args.service = "getprop"; | ||
178 | args.nargs = 4; | ||
179 | args.nret = 1; | ||
180 | args.phandle = phandle; | ||
181 | args.name = name; | ||
182 | args.buf = buf; | ||
183 | args.buflen = buflen; | ||
184 | args.size = -1; | ||
185 | (*prom)(&args); | ||
186 | return args.size; | ||
187 | } | ||
188 | |||
189 | int | ||
190 | putc(int c, void *f) | ||
191 | { | ||
192 | char ch = c; | ||
193 | |||
194 | if (c == '\n') | ||
195 | putc('\r', f); | ||
196 | return write(f, &ch, 1) == 1? c: -1; | ||
197 | } | ||
198 | |||
199 | int | ||
200 | putchar(int c) | ||
201 | { | ||
202 | return putc(c, stdout); | ||
203 | } | ||
204 | |||
205 | int | ||
206 | fputs(char *str, void *f) | ||
207 | { | ||
208 | int n = strlen(str); | ||
209 | |||
210 | return write(f, str, n) == n? 0: -1; | ||
211 | } | ||
212 | |||
213 | int | ||
214 | readchar(void) | ||
215 | { | ||
216 | char ch; | ||
217 | |||
218 | for (;;) { | ||
219 | switch (read(stdin, &ch, 1)) { | ||
220 | case 1: | ||
221 | return ch; | ||
222 | case -1: | ||
223 | printk("read(stdin) returned -1\r\n"); | ||
224 | return -1; | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | |||
229 | static char line[256]; | ||
230 | static char *lineptr; | ||
231 | static int lineleft; | ||
232 | |||
233 | int | ||
234 | getchar(void) | ||
235 | { | ||
236 | int c; | ||
237 | |||
238 | if (lineleft == 0) { | ||
239 | lineptr = line; | ||
240 | for (;;) { | ||
241 | c = readchar(); | ||
242 | if (c == -1 || c == 4) | ||
243 | break; | ||
244 | if (c == '\r' || c == '\n') { | ||
245 | *lineptr++ = '\n'; | ||
246 | putchar('\n'); | ||
247 | break; | ||
248 | } | ||
249 | switch (c) { | ||
250 | case 0177: | ||
251 | case '\b': | ||
252 | if (lineptr > line) { | ||
253 | putchar('\b'); | ||
254 | putchar(' '); | ||
255 | putchar('\b'); | ||
256 | --lineptr; | ||
257 | } | ||
258 | break; | ||
259 | case 'U' & 0x1F: | ||
260 | while (lineptr > line) { | ||
261 | putchar('\b'); | ||
262 | putchar(' '); | ||
263 | putchar('\b'); | ||
264 | --lineptr; | ||
265 | } | ||
266 | break; | ||
267 | default: | ||
268 | if (lineptr >= &line[sizeof(line) - 1]) | ||
269 | putchar('\a'); | ||
270 | else { | ||
271 | putchar(c); | ||
272 | *lineptr++ = c; | ||
273 | } | ||
274 | } | ||
275 | } | ||
276 | lineleft = lineptr - line; | ||
277 | lineptr = line; | ||
278 | } | ||
279 | if (lineleft == 0) | ||
280 | return -1; | ||
281 | --lineleft; | ||
282 | return *lineptr++; | ||
283 | } | ||
284 | |||
285 | |||
286 | |||
287 | /* String functions lifted from lib/vsprintf.c and lib/ctype.c */ | ||
288 | unsigned char _ctype[] = { | ||
289 | _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ | ||
290 | _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ | ||
291 | _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ | ||
292 | _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ | ||
293 | _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ | ||
294 | _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ | ||
295 | _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ | ||
296 | _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ | ||
297 | _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ | ||
298 | _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ | ||
299 | _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ | ||
300 | _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ | ||
301 | _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ | ||
302 | _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ | ||
303 | _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ | ||
304 | _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ | ||
305 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ | ||
306 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ | ||
307 | _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ | ||
308 | _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ | ||
309 | _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ | ||
310 | _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ | ||
311 | _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ | ||
312 | _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ | ||
313 | |||
314 | size_t strnlen(const char * s, size_t count) | ||
315 | { | ||
316 | const char *sc; | ||
317 | |||
318 | for (sc = s; count-- && *sc != '\0'; ++sc) | ||
319 | /* nothing */; | ||
320 | return sc - s; | ||
321 | } | ||
322 | |||
323 | unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) | ||
324 | { | ||
325 | unsigned long result = 0,value; | ||
326 | |||
327 | if (!base) { | ||
328 | base = 10; | ||
329 | if (*cp == '0') { | ||
330 | base = 8; | ||
331 | cp++; | ||
332 | if ((*cp == 'x') && isxdigit(cp[1])) { | ||
333 | cp++; | ||
334 | base = 16; | ||
335 | } | ||
336 | } | ||
337 | } | ||
338 | while (isxdigit(*cp) && | ||
339 | (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { | ||
340 | result = result*base + value; | ||
341 | cp++; | ||
342 | } | ||
343 | if (endp) | ||
344 | *endp = (char *)cp; | ||
345 | return result; | ||
346 | } | ||
347 | |||
348 | long simple_strtol(const char *cp,char **endp,unsigned int base) | ||
349 | { | ||
350 | if(*cp=='-') | ||
351 | return -simple_strtoul(cp+1,endp,base); | ||
352 | return simple_strtoul(cp,endp,base); | ||
353 | } | ||
354 | |||
355 | static int skip_atoi(const char **s) | ||
356 | { | ||
357 | int i=0; | ||
358 | |||
359 | while (isdigit(**s)) | ||
360 | i = i*10 + *((*s)++) - '0'; | ||
361 | return i; | ||
362 | } | ||
363 | |||
364 | #define ZEROPAD 1 /* pad with zero */ | ||
365 | #define SIGN 2 /* unsigned/signed long */ | ||
366 | #define PLUS 4 /* show plus */ | ||
367 | #define SPACE 8 /* space if plus */ | ||
368 | #define LEFT 16 /* left justified */ | ||
369 | #define SPECIAL 32 /* 0x */ | ||
370 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ | ||
371 | |||
372 | static char * number(char * str, long long num, int base, int size, int precision, int type) | ||
373 | { | ||
374 | char c,sign,tmp[66]; | ||
375 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; | ||
376 | int i; | ||
377 | |||
378 | if (type & LARGE) | ||
379 | digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
380 | if (type & LEFT) | ||
381 | type &= ~ZEROPAD; | ||
382 | if (base < 2 || base > 36) | ||
383 | return 0; | ||
384 | c = (type & ZEROPAD) ? '0' : ' '; | ||
385 | sign = 0; | ||
386 | if (type & SIGN) { | ||
387 | if (num < 0) { | ||
388 | sign = '-'; | ||
389 | num = -num; | ||
390 | size--; | ||
391 | } else if (type & PLUS) { | ||
392 | sign = '+'; | ||
393 | size--; | ||
394 | } else if (type & SPACE) { | ||
395 | sign = ' '; | ||
396 | size--; | ||
397 | } | ||
398 | } | ||
399 | if (type & SPECIAL) { | ||
400 | if (base == 16) | ||
401 | size -= 2; | ||
402 | else if (base == 8) | ||
403 | size--; | ||
404 | } | ||
405 | i = 0; | ||
406 | if (num == 0) | ||
407 | tmp[i++]='0'; | ||
408 | else while (num != 0) | ||
409 | tmp[i++] = digits[do_div(num,base)]; | ||
410 | if (i > precision) | ||
411 | precision = i; | ||
412 | size -= precision; | ||
413 | if (!(type&(ZEROPAD+LEFT))) | ||
414 | while(size-->0) | ||
415 | *str++ = ' '; | ||
416 | if (sign) | ||
417 | *str++ = sign; | ||
418 | if (type & SPECIAL) { | ||
419 | if (base==8) | ||
420 | *str++ = '0'; | ||
421 | else if (base==16) { | ||
422 | *str++ = '0'; | ||
423 | *str++ = digits[33]; | ||
424 | } | ||
425 | } | ||
426 | if (!(type & LEFT)) | ||
427 | while (size-- > 0) | ||
428 | *str++ = c; | ||
429 | while (i < precision--) | ||
430 | *str++ = '0'; | ||
431 | while (i-- > 0) | ||
432 | *str++ = tmp[i]; | ||
433 | while (size-- > 0) | ||
434 | *str++ = ' '; | ||
435 | return str; | ||
436 | } | ||
437 | |||
438 | /* Forward decl. needed for IP address printing stuff... */ | ||
439 | int sprintf(char * buf, const char *fmt, ...); | ||
440 | |||
441 | int vsprintf(char *buf, const char *fmt, va_list args) | ||
442 | { | ||
443 | int len; | ||
444 | unsigned long long num; | ||
445 | int i, base; | ||
446 | char * str; | ||
447 | const char *s; | ||
448 | |||
449 | int flags; /* flags to number() */ | ||
450 | |||
451 | int field_width; /* width of output field */ | ||
452 | int precision; /* min. # of digits for integers; max | ||
453 | number of chars for from string */ | ||
454 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ | ||
455 | /* 'z' support added 23/7/1999 S.H. */ | ||
456 | /* 'z' changed to 'Z' --davidm 1/25/99 */ | ||
457 | |||
458 | |||
459 | for (str=buf ; *fmt ; ++fmt) { | ||
460 | if (*fmt != '%') { | ||
461 | *str++ = *fmt; | ||
462 | continue; | ||
463 | } | ||
464 | |||
465 | /* process flags */ | ||
466 | flags = 0; | ||
467 | repeat: | ||
468 | ++fmt; /* this also skips first '%' */ | ||
469 | switch (*fmt) { | ||
470 | case '-': flags |= LEFT; goto repeat; | ||
471 | case '+': flags |= PLUS; goto repeat; | ||
472 | case ' ': flags |= SPACE; goto repeat; | ||
473 | case '#': flags |= SPECIAL; goto repeat; | ||
474 | case '0': flags |= ZEROPAD; goto repeat; | ||
475 | } | ||
476 | |||
477 | /* get field width */ | ||
478 | field_width = -1; | ||
479 | if (isdigit(*fmt)) | ||
480 | field_width = skip_atoi(&fmt); | ||
481 | else if (*fmt == '*') { | ||
482 | ++fmt; | ||
483 | /* it's the next argument */ | ||
484 | field_width = va_arg(args, int); | ||
485 | if (field_width < 0) { | ||
486 | field_width = -field_width; | ||
487 | flags |= LEFT; | ||
488 | } | ||
489 | } | ||
490 | |||
491 | /* get the precision */ | ||
492 | precision = -1; | ||
493 | if (*fmt == '.') { | ||
494 | ++fmt; | ||
495 | if (isdigit(*fmt)) | ||
496 | precision = skip_atoi(&fmt); | ||
497 | else if (*fmt == '*') { | ||
498 | ++fmt; | ||
499 | /* it's the next argument */ | ||
500 | precision = va_arg(args, int); | ||
501 | } | ||
502 | if (precision < 0) | ||
503 | precision = 0; | ||
504 | } | ||
505 | |||
506 | /* get the conversion qualifier */ | ||
507 | qualifier = -1; | ||
508 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { | ||
509 | qualifier = *fmt; | ||
510 | ++fmt; | ||
511 | } | ||
512 | |||
513 | /* default base */ | ||
514 | base = 10; | ||
515 | |||
516 | switch (*fmt) { | ||
517 | case 'c': | ||
518 | if (!(flags & LEFT)) | ||
519 | while (--field_width > 0) | ||
520 | *str++ = ' '; | ||
521 | *str++ = (unsigned char) va_arg(args, int); | ||
522 | while (--field_width > 0) | ||
523 | *str++ = ' '; | ||
524 | continue; | ||
525 | |||
526 | case 's': | ||
527 | s = va_arg(args, char *); | ||
528 | if (!s) | ||
529 | s = "<NULL>"; | ||
530 | |||
531 | len = strnlen(s, precision); | ||
532 | |||
533 | if (!(flags & LEFT)) | ||
534 | while (len < field_width--) | ||
535 | *str++ = ' '; | ||
536 | for (i = 0; i < len; ++i) | ||
537 | *str++ = *s++; | ||
538 | while (len < field_width--) | ||
539 | *str++ = ' '; | ||
540 | continue; | ||
541 | |||
542 | case 'p': | ||
543 | if (field_width == -1) { | ||
544 | field_width = 2*sizeof(void *); | ||
545 | flags |= ZEROPAD; | ||
546 | } | ||
547 | str = number(str, | ||
548 | (unsigned long) va_arg(args, void *), 16, | ||
549 | field_width, precision, flags); | ||
550 | continue; | ||
551 | |||
552 | |||
553 | case 'n': | ||
554 | if (qualifier == 'l') { | ||
555 | long * ip = va_arg(args, long *); | ||
556 | *ip = (str - buf); | ||
557 | } else if (qualifier == 'Z') { | ||
558 | size_t * ip = va_arg(args, size_t *); | ||
559 | *ip = (str - buf); | ||
560 | } else { | ||
561 | int * ip = va_arg(args, int *); | ||
562 | *ip = (str - buf); | ||
563 | } | ||
564 | continue; | ||
565 | |||
566 | case '%': | ||
567 | *str++ = '%'; | ||
568 | continue; | ||
569 | |||
570 | /* integer number formats - set up the flags and "break" */ | ||
571 | case 'o': | ||
572 | base = 8; | ||
573 | break; | ||
574 | |||
575 | case 'X': | ||
576 | flags |= LARGE; | ||
577 | case 'x': | ||
578 | base = 16; | ||
579 | break; | ||
580 | |||
581 | case 'd': | ||
582 | case 'i': | ||
583 | flags |= SIGN; | ||
584 | case 'u': | ||
585 | break; | ||
586 | |||
587 | default: | ||
588 | *str++ = '%'; | ||
589 | if (*fmt) | ||
590 | *str++ = *fmt; | ||
591 | else | ||
592 | --fmt; | ||
593 | continue; | ||
594 | } | ||
595 | if (qualifier == 'L') | ||
596 | num = va_arg(args, long long); | ||
597 | else if (qualifier == 'l') { | ||
598 | num = va_arg(args, unsigned long); | ||
599 | if (flags & SIGN) | ||
600 | num = (signed long) num; | ||
601 | } else if (qualifier == 'Z') { | ||
602 | num = va_arg(args, size_t); | ||
603 | } else if (qualifier == 'h') { | ||
604 | num = (unsigned short) va_arg(args, int); | ||
605 | if (flags & SIGN) | ||
606 | num = (signed short) num; | ||
607 | } else { | ||
608 | num = va_arg(args, unsigned int); | ||
609 | if (flags & SIGN) | ||
610 | num = (signed int) num; | ||
611 | } | ||
612 | str = number(str, num, base, field_width, precision, flags); | ||
613 | } | ||
614 | *str = '\0'; | ||
615 | return str-buf; | ||
616 | } | ||
617 | |||
618 | int sprintf(char * buf, const char *fmt, ...) | ||
619 | { | ||
620 | va_list args; | ||
621 | int i; | ||
622 | |||
623 | va_start(args, fmt); | ||
624 | i=vsprintf(buf,fmt,args); | ||
625 | va_end(args); | ||
626 | return i; | ||
627 | } | ||
628 | |||
629 | static char sprint_buf[1024]; | ||
630 | |||
631 | void | ||
632 | printk(char *fmt, ...) | ||
633 | { | ||
634 | va_list args; | ||
635 | int n; | ||
636 | |||
637 | va_start(args, fmt); | ||
638 | n = vsprintf(sprint_buf, fmt, args); | ||
639 | va_end(args); | ||
640 | write(stdout, sprint_buf, n); | ||
641 | } | ||
642 | |||
643 | int | ||
644 | printf(char *fmt, ...) | ||
645 | { | ||
646 | va_list args; | ||
647 | int n; | ||
648 | |||
649 | va_start(args, fmt); | ||
650 | n = vsprintf(sprint_buf, fmt, args); | ||
651 | va_end(args); | ||
652 | write(stdout, sprint_buf, n); | ||
653 | return n; | ||
654 | } | ||
diff --git a/arch/ppc64/boot/string.S b/arch/ppc64/boot/string.S new file mode 100644 index 00000000000..ba5f2d21c9e --- /dev/null +++ b/arch/ppc64/boot/string.S | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * NOTE: this code runs in 32 bit mode and is packaged as ELF32. | ||
10 | */ | ||
11 | |||
12 | #include <asm/ppc_asm.h> | ||
13 | |||
14 | .text | ||
15 | .globl strcpy | ||
16 | strcpy: | ||
17 | addi r5,r3,-1 | ||
18 | addi r4,r4,-1 | ||
19 | 1: lbzu r0,1(r4) | ||
20 | cmpwi 0,r0,0 | ||
21 | stbu r0,1(r5) | ||
22 | bne 1b | ||
23 | blr | ||
24 | |||
25 | .globl strncpy | ||
26 | strncpy: | ||
27 | cmpwi 0,r5,0 | ||
28 | beqlr | ||
29 | mtctr r5 | ||
30 | addi r6,r3,-1 | ||
31 | addi r4,r4,-1 | ||
32 | 1: lbzu r0,1(r4) | ||
33 | cmpwi 0,r0,0 | ||
34 | stbu r0,1(r6) | ||
35 | bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ | ||
36 | blr | ||
37 | |||
38 | .globl strcat | ||
39 | strcat: | ||
40 | addi r5,r3,-1 | ||
41 | addi r4,r4,-1 | ||
42 | 1: lbzu r0,1(r5) | ||
43 | cmpwi 0,r0,0 | ||
44 | bne 1b | ||
45 | addi r5,r5,-1 | ||
46 | 1: lbzu r0,1(r4) | ||
47 | cmpwi 0,r0,0 | ||
48 | stbu r0,1(r5) | ||
49 | bne 1b | ||
50 | blr | ||
51 | |||
52 | .globl strcmp | ||
53 | strcmp: | ||
54 | addi r5,r3,-1 | ||
55 | addi r4,r4,-1 | ||
56 | 1: lbzu r3,1(r5) | ||
57 | cmpwi 1,r3,0 | ||
58 | lbzu r0,1(r4) | ||
59 | subf. r3,r0,r3 | ||
60 | beqlr 1 | ||
61 | beq 1b | ||
62 | blr | ||
63 | |||
64 | .globl strlen | ||
65 | strlen: | ||
66 | addi r4,r3,-1 | ||
67 | 1: lbzu r0,1(r4) | ||
68 | cmpwi 0,r0,0 | ||
69 | bne 1b | ||
70 | subf r3,r3,r4 | ||
71 | blr | ||
72 | |||
73 | .globl memset | ||
74 | memset: | ||
75 | rlwimi r4,r4,8,16,23 | ||
76 | rlwimi r4,r4,16,0,15 | ||
77 | addi r6,r3,-4 | ||
78 | cmplwi 0,r5,4 | ||
79 | blt 7f | ||
80 | stwu r4,4(r6) | ||
81 | beqlr | ||
82 | andi. r0,r6,3 | ||
83 | add r5,r0,r5 | ||
84 | subf r6,r0,r6 | ||
85 | rlwinm r0,r5,32-2,2,31 | ||
86 | mtctr r0 | ||
87 | bdz 6f | ||
88 | 1: stwu r4,4(r6) | ||
89 | bdnz 1b | ||
90 | 6: andi. r5,r5,3 | ||
91 | 7: cmpwi 0,r5,0 | ||
92 | beqlr | ||
93 | mtctr r5 | ||
94 | addi r6,r6,3 | ||
95 | 8: stbu r4,1(r6) | ||
96 | bdnz 8b | ||
97 | blr | ||
98 | |||
99 | .globl memmove | ||
100 | memmove: | ||
101 | cmplw 0,r3,r4 | ||
102 | bgt backwards_memcpy | ||
103 | /* fall through */ | ||
104 | |||
105 | .globl memcpy | ||
106 | memcpy: | ||
107 | rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ | ||
108 | addi r6,r3,-4 | ||
109 | addi r4,r4,-4 | ||
110 | beq 2f /* if less than 8 bytes to do */ | ||
111 | andi. r0,r6,3 /* get dest word aligned */ | ||
112 | mtctr r7 | ||
113 | bne 5f | ||
114 | 1: lwz r7,4(r4) | ||
115 | lwzu r8,8(r4) | ||
116 | stw r7,4(r6) | ||
117 | stwu r8,8(r6) | ||
118 | bdnz 1b | ||
119 | andi. r5,r5,7 | ||
120 | 2: cmplwi 0,r5,4 | ||
121 | blt 3f | ||
122 | lwzu r0,4(r4) | ||
123 | addi r5,r5,-4 | ||
124 | stwu r0,4(r6) | ||
125 | 3: cmpwi 0,r5,0 | ||
126 | beqlr | ||
127 | mtctr r5 | ||
128 | addi r4,r4,3 | ||
129 | addi r6,r6,3 | ||
130 | 4: lbzu r0,1(r4) | ||
131 | stbu r0,1(r6) | ||
132 | bdnz 4b | ||
133 | blr | ||
134 | 5: subfic r0,r0,4 | ||
135 | mtctr r0 | ||
136 | 6: lbz r7,4(r4) | ||
137 | addi r4,r4,1 | ||
138 | stb r7,4(r6) | ||
139 | addi r6,r6,1 | ||
140 | bdnz 6b | ||
141 | subf r5,r0,r5 | ||
142 | rlwinm. r7,r5,32-3,3,31 | ||
143 | beq 2b | ||
144 | mtctr r7 | ||
145 | b 1b | ||
146 | |||
147 | .globl backwards_memcpy | ||
148 | backwards_memcpy: | ||
149 | rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ | ||
150 | add r6,r3,r5 | ||
151 | add r4,r4,r5 | ||
152 | beq 2f | ||
153 | andi. r0,r6,3 | ||
154 | mtctr r7 | ||
155 | bne 5f | ||
156 | 1: lwz r7,-4(r4) | ||
157 | lwzu r8,-8(r4) | ||
158 | stw r7,-4(r6) | ||
159 | stwu r8,-8(r6) | ||
160 | bdnz 1b | ||
161 | andi. r5,r5,7 | ||
162 | 2: cmplwi 0,r5,4 | ||
163 | blt 3f | ||
164 | lwzu r0,-4(r4) | ||
165 | subi r5,r5,4 | ||
166 | stwu r0,-4(r6) | ||
167 | 3: cmpwi 0,r5,0 | ||
168 | beqlr | ||
169 | mtctr r5 | ||
170 | 4: lbzu r0,-1(r4) | ||
171 | stbu r0,-1(r6) | ||
172 | bdnz 4b | ||
173 | blr | ||
174 | 5: mtctr r0 | ||
175 | 6: lbzu r7,-1(r4) | ||
176 | stbu r7,-1(r6) | ||
177 | bdnz 6b | ||
178 | subf r5,r0,r5 | ||
179 | rlwinm. r7,r5,32-3,3,31 | ||
180 | beq 2b | ||
181 | mtctr r7 | ||
182 | b 1b | ||
183 | |||
184 | .globl memcmp | ||
185 | memcmp: | ||
186 | cmpwi 0,r5,0 | ||
187 | blelr | ||
188 | mtctr r5 | ||
189 | addi r6,r3,-1 | ||
190 | addi r4,r4,-1 | ||
191 | 1: lbzu r3,1(r6) | ||
192 | lbzu r0,1(r4) | ||
193 | subf. r3,r0,r3 | ||
194 | bdnzt 2,1b | ||
195 | blr | ||
196 | |||
197 | |||
198 | /* | ||
199 | * Flush the dcache and invalidate the icache for a range of addresses. | ||
200 | * | ||
201 | * flush_cache(addr, len) | ||
202 | */ | ||
203 | .global flush_cache | ||
204 | flush_cache: | ||
205 | addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ | ||
206 | rlwinm. 4,4,27,5,31 | ||
207 | mtctr 4 | ||
208 | beqlr | ||
209 | 1: dcbf 0,3 | ||
210 | icbi 0,3 | ||
211 | addi 3,3,0x20 | ||
212 | bdnz 1b | ||
213 | sync | ||
214 | isync | ||
215 | blr | ||
216 | |||
diff --git a/arch/ppc64/boot/zImage.lds b/arch/ppc64/boot/zImage.lds new file mode 100644 index 00000000000..8fe5e7071f5 --- /dev/null +++ b/arch/ppc64/boot/zImage.lds | |||
@@ -0,0 +1,90 @@ | |||
1 | OUTPUT_ARCH(powerpc:common) | ||
2 | SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); | ||
3 | /* Do we need any of these for elf? | ||
4 | __DYNAMIC = 0; */ | ||
5 | SECTIONS | ||
6 | { | ||
7 | /* Read-only sections, merged into text segment: */ | ||
8 | . = + SIZEOF_HEADERS; | ||
9 | .interp : { *(.interp) } | ||
10 | .hash : { *(.hash) } | ||
11 | .dynsym : { *(.dynsym) } | ||
12 | .dynstr : { *(.dynstr) } | ||
13 | .rel.text : { *(.rel.text) } | ||
14 | .rela.text : { *(.rela.text) } | ||
15 | .rel.data : { *(.rel.data) } | ||
16 | .rela.data : { *(.rela.data) } | ||
17 | .rel.rodata : { *(.rel.rodata) } | ||
18 | .rela.rodata : { *(.rela.rodata) } | ||
19 | .rel.got : { *(.rel.got) } | ||
20 | .rela.got : { *(.rela.got) } | ||
21 | .rel.ctors : { *(.rel.ctors) } | ||
22 | .rela.ctors : { *(.rela.ctors) } | ||
23 | .rel.dtors : { *(.rel.dtors) } | ||
24 | .rela.dtors : { *(.rela.dtors) } | ||
25 | .rel.bss : { *(.rel.bss) } | ||
26 | .rela.bss : { *(.rela.bss) } | ||
27 | .rel.plt : { *(.rel.plt) } | ||
28 | .rela.plt : { *(.rela.plt) } | ||
29 | .plt : { *(.plt) } | ||
30 | .text : | ||
31 | { | ||
32 | *(.text) | ||
33 | *(.fixup) | ||
34 | *(.got1) | ||
35 | } | ||
36 | . = ALIGN(4096); | ||
37 | _etext = .; | ||
38 | PROVIDE (etext = .); | ||
39 | .rodata : | ||
40 | { | ||
41 | *(.rodata) | ||
42 | *(.rodata1) | ||
43 | } | ||
44 | .kstrtab : { *(.kstrtab) } | ||
45 | __vermagic : { *(__vermagic) } | ||
46 | .fini : { *(.fini) } =0 | ||
47 | .ctors : { *(.ctors) } | ||
48 | .dtors : { *(.dtors) } | ||
49 | /* Read-write section, merged into data segment: */ | ||
50 | . = ALIGN(4096); | ||
51 | .data : | ||
52 | { | ||
53 | *(.data) | ||
54 | *(.data1) | ||
55 | *(.sdata) | ||
56 | *(.sdata2) | ||
57 | *(.got.plt) *(.got) | ||
58 | *(.dynamic) | ||
59 | CONSTRUCTORS | ||
60 | } | ||
61 | |||
62 | . = ALIGN(4096); | ||
63 | _vmlinux_start = .; | ||
64 | .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) } | ||
65 | _vmlinux_end = .; | ||
66 | |||
67 | . = ALIGN(4096); | ||
68 | _initrd_start = .; | ||
69 | .kernel:initrd : { *(.kernel:initrd) } | ||
70 | _initrd_end = .; | ||
71 | |||
72 | . = ALIGN(4096); | ||
73 | _edata = .; | ||
74 | PROVIDE (edata = .); | ||
75 | |||
76 | .fixup : { *(.fixup) } | ||
77 | |||
78 | . = ALIGN(4096); | ||
79 | __bss_start = .; | ||
80 | .bss : | ||
81 | { | ||
82 | *(.sbss) *(.scommon) | ||
83 | *(.dynbss) | ||
84 | *(.bss) | ||
85 | *(COMMON) | ||
86 | } | ||
87 | . = ALIGN(4096); | ||
88 | _end = . ; | ||
89 | PROVIDE (end = .); | ||
90 | } | ||
diff --git a/arch/ppc64/boot/zlib.c b/arch/ppc64/boot/zlib.c new file mode 100644 index 00000000000..9d5e4e9832d --- /dev/null +++ b/arch/ppc64/boot/zlib.c | |||
@@ -0,0 +1,2194 @@ | |||
1 | /* | ||
2 | * This file is derived from various .h and .c files from the zlib-0.95 | ||
3 | * distribution by Jean-loup Gailly and Mark Adler, with some additions | ||
4 | * by Paul Mackerras to aid in implementing Deflate compression and | ||
5 | * decompression for PPP packets. See zlib.h for conditions of | ||
6 | * distribution and use. | ||
7 | * | ||
8 | * Changes that have been made include: | ||
9 | * - changed functions not used outside this file to "local" | ||
10 | * - added minCompression parameter to deflateInit2 | ||
11 | * - added Z_PACKET_FLUSH (see zlib.h for details) | ||
12 | * - added inflateIncomp | ||
13 | * | ||
14 | Copyright (C) 1995 Jean-loup Gailly and Mark Adler | ||
15 | |||
16 | This software is provided 'as-is', without any express or implied | ||
17 | warranty. In no event will the authors be held liable for any damages | ||
18 | arising from the use of this software. | ||
19 | |||
20 | Permission is granted to anyone to use this software for any purpose, | ||
21 | including commercial applications, and to alter it and redistribute it | ||
22 | freely, subject to the following restrictions: | ||
23 | |||
24 | 1. The origin of this software must not be misrepresented; you must not | ||
25 | claim that you wrote the original software. If you use this software | ||
26 | in a product, an acknowledgment in the product documentation would be | ||
27 | appreciated but is not required. | ||
28 | 2. Altered source versions must be plainly marked as such, and must not be | ||
29 | misrepresented as being the original software. | ||
30 | 3. This notice may not be removed or altered from any source distribution. | ||
31 | |||
32 | Jean-loup Gailly Mark Adler | ||
33 | gzip@prep.ai.mit.edu madler@alumni.caltech.edu | ||
34 | |||
35 | * | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | /*+++++*/ | ||
40 | /* zutil.h -- internal interface and configuration of the compression library | ||
41 | * Copyright (C) 1995 Jean-loup Gailly. | ||
42 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
43 | */ | ||
44 | |||
45 | /* WARNING: this file should *not* be used by applications. It is | ||
46 | part of the implementation of the compression library and is | ||
47 | subject to change. Applications should only use zlib.h. | ||
48 | */ | ||
49 | |||
50 | /* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */ | ||
51 | |||
52 | #define _Z_UTIL_H | ||
53 | |||
54 | #include "zlib.h" | ||
55 | |||
56 | #ifndef local | ||
57 | # define local static | ||
58 | #endif | ||
59 | /* compile with -Dlocal if your debugger can't find static symbols */ | ||
60 | |||
61 | #define FAR | ||
62 | |||
63 | typedef unsigned char uch; | ||
64 | typedef uch FAR uchf; | ||
65 | typedef unsigned short ush; | ||
66 | typedef ush FAR ushf; | ||
67 | typedef unsigned long ulg; | ||
68 | |||
69 | extern char *z_errmsg[]; /* indexed by 1-zlib_error */ | ||
70 | |||
71 | #define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) | ||
72 | /* To be used only when the state is known to be valid */ | ||
73 | |||
74 | #ifndef NULL | ||
75 | #define NULL ((void *) 0) | ||
76 | #endif | ||
77 | |||
78 | /* common constants */ | ||
79 | |||
80 | #define DEFLATED 8 | ||
81 | |||
82 | #ifndef DEF_WBITS | ||
83 | # define DEF_WBITS MAX_WBITS | ||
84 | #endif | ||
85 | /* default windowBits for decompression. MAX_WBITS is for compression only */ | ||
86 | |||
87 | #if MAX_MEM_LEVEL >= 8 | ||
88 | # define DEF_MEM_LEVEL 8 | ||
89 | #else | ||
90 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL | ||
91 | #endif | ||
92 | /* default memLevel */ | ||
93 | |||
94 | #define STORED_BLOCK 0 | ||
95 | #define STATIC_TREES 1 | ||
96 | #define DYN_TREES 2 | ||
97 | /* The three kinds of block type */ | ||
98 | |||
99 | #define MIN_MATCH 3 | ||
100 | #define MAX_MATCH 258 | ||
101 | /* The minimum and maximum match lengths */ | ||
102 | |||
103 | /* functions */ | ||
104 | |||
105 | extern void *memcpy(void *, const void *, unsigned long); | ||
106 | #define zmemcpy memcpy | ||
107 | |||
108 | /* Diagnostic functions */ | ||
109 | #ifdef DEBUG_ZLIB | ||
110 | # include <stdio.h> | ||
111 | # ifndef verbose | ||
112 | # define verbose 0 | ||
113 | # endif | ||
114 | # define Assert(cond,msg) {if(!(cond)) z_error(msg);} | ||
115 | # define Trace(x) fprintf x | ||
116 | # define Tracev(x) {if (verbose) fprintf x ;} | ||
117 | # define Tracevv(x) {if (verbose>1) fprintf x ;} | ||
118 | # define Tracec(c,x) {if (verbose && (c)) fprintf x ;} | ||
119 | # define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} | ||
120 | #else | ||
121 | # define Assert(cond,msg) | ||
122 | # define Trace(x) | ||
123 | # define Tracev(x) | ||
124 | # define Tracevv(x) | ||
125 | # define Tracec(c,x) | ||
126 | # define Tracecv(c,x) | ||
127 | #endif | ||
128 | |||
129 | |||
130 | typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); | ||
131 | |||
132 | /* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ | ||
133 | /* void zcfree OF((voidpf opaque, voidpf ptr)); */ | ||
134 | |||
135 | #define ZALLOC(strm, items, size) \ | ||
136 | (*((strm)->zalloc))((strm)->opaque, (items), (size)) | ||
137 | #define ZFREE(strm, addr, size) \ | ||
138 | (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) | ||
139 | #define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} | ||
140 | |||
141 | /* deflate.h -- internal compression state | ||
142 | * Copyright (C) 1995 Jean-loup Gailly | ||
143 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
144 | */ | ||
145 | |||
146 | /* WARNING: this file should *not* be used by applications. It is | ||
147 | part of the implementation of the compression library and is | ||
148 | subject to change. Applications should only use zlib.h. | ||
149 | */ | ||
150 | |||
151 | /*+++++*/ | ||
152 | /* infblock.h -- header to use infblock.c | ||
153 | * Copyright (C) 1995 Mark Adler | ||
154 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
155 | */ | ||
156 | |||
157 | /* WARNING: this file should *not* be used by applications. It is | ||
158 | part of the implementation of the compression library and is | ||
159 | subject to change. Applications should only use zlib.h. | ||
160 | */ | ||
161 | |||
162 | struct inflate_blocks_state; | ||
163 | typedef struct inflate_blocks_state FAR inflate_blocks_statef; | ||
164 | |||
165 | local inflate_blocks_statef * inflate_blocks_new OF(( | ||
166 | z_stream *z, | ||
167 | check_func c, /* check function */ | ||
168 | uInt w)); /* window size */ | ||
169 | |||
170 | local int inflate_blocks OF(( | ||
171 | inflate_blocks_statef *, | ||
172 | z_stream *, | ||
173 | int)); /* initial return code */ | ||
174 | |||
175 | local void inflate_blocks_reset OF(( | ||
176 | inflate_blocks_statef *, | ||
177 | z_stream *, | ||
178 | uLongf *)); /* check value on output */ | ||
179 | |||
180 | local int inflate_blocks_free OF(( | ||
181 | inflate_blocks_statef *, | ||
182 | z_stream *, | ||
183 | uLongf *)); /* check value on output */ | ||
184 | |||
185 | local int inflate_addhistory OF(( | ||
186 | inflate_blocks_statef *, | ||
187 | z_stream *)); | ||
188 | |||
189 | local int inflate_packet_flush OF(( | ||
190 | inflate_blocks_statef *)); | ||
191 | |||
192 | /*+++++*/ | ||
193 | /* inftrees.h -- header to use inftrees.c | ||
194 | * Copyright (C) 1995 Mark Adler | ||
195 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
196 | */ | ||
197 | |||
198 | /* WARNING: this file should *not* be used by applications. It is | ||
199 | part of the implementation of the compression library and is | ||
200 | subject to change. Applications should only use zlib.h. | ||
201 | */ | ||
202 | |||
203 | /* Huffman code lookup table entry--this entry is four bytes for machines | ||
204 | that have 16-bit pointers (e.g. PC's in the small or medium model). */ | ||
205 | |||
206 | typedef struct inflate_huft_s FAR inflate_huft; | ||
207 | |||
208 | struct inflate_huft_s { | ||
209 | union { | ||
210 | struct { | ||
211 | Byte Exop; /* number of extra bits or operation */ | ||
212 | Byte Bits; /* number of bits in this code or subcode */ | ||
213 | } what; | ||
214 | uInt Nalloc; /* number of these allocated here */ | ||
215 | Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ | ||
216 | } word; /* 16-bit, 8 bytes for 32-bit machines) */ | ||
217 | union { | ||
218 | uInt Base; /* literal, length base, or distance base */ | ||
219 | inflate_huft *Next; /* pointer to next level of table */ | ||
220 | } more; | ||
221 | }; | ||
222 | |||
223 | #ifdef DEBUG_ZLIB | ||
224 | local uInt inflate_hufts; | ||
225 | #endif | ||
226 | |||
227 | local int inflate_trees_bits OF(( | ||
228 | uIntf *, /* 19 code lengths */ | ||
229 | uIntf *, /* bits tree desired/actual depth */ | ||
230 | inflate_huft * FAR *, /* bits tree result */ | ||
231 | z_stream *)); /* for zalloc, zfree functions */ | ||
232 | |||
233 | local int inflate_trees_dynamic OF(( | ||
234 | uInt, /* number of literal/length codes */ | ||
235 | uInt, /* number of distance codes */ | ||
236 | uIntf *, /* that many (total) code lengths */ | ||
237 | uIntf *, /* literal desired/actual bit depth */ | ||
238 | uIntf *, /* distance desired/actual bit depth */ | ||
239 | inflate_huft * FAR *, /* literal/length tree result */ | ||
240 | inflate_huft * FAR *, /* distance tree result */ | ||
241 | z_stream *)); /* for zalloc, zfree functions */ | ||
242 | |||
243 | local int inflate_trees_fixed OF(( | ||
244 | uIntf *, /* literal desired/actual bit depth */ | ||
245 | uIntf *, /* distance desired/actual bit depth */ | ||
246 | inflate_huft * FAR *, /* literal/length tree result */ | ||
247 | inflate_huft * FAR *)); /* distance tree result */ | ||
248 | |||
249 | local int inflate_trees_free OF(( | ||
250 | inflate_huft *, /* tables to free */ | ||
251 | z_stream *)); /* for zfree function */ | ||
252 | |||
253 | |||
254 | /*+++++*/ | ||
255 | /* infcodes.h -- header to use infcodes.c | ||
256 | * Copyright (C) 1995 Mark Adler | ||
257 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
258 | */ | ||
259 | |||
260 | /* WARNING: this file should *not* be used by applications. It is | ||
261 | part of the implementation of the compression library and is | ||
262 | subject to change. Applications should only use zlib.h. | ||
263 | */ | ||
264 | |||
265 | struct inflate_codes_state; | ||
266 | typedef struct inflate_codes_state FAR inflate_codes_statef; | ||
267 | |||
268 | local inflate_codes_statef *inflate_codes_new OF(( | ||
269 | uInt, uInt, | ||
270 | inflate_huft *, inflate_huft *, | ||
271 | z_stream *)); | ||
272 | |||
273 | local int inflate_codes OF(( | ||
274 | inflate_blocks_statef *, | ||
275 | z_stream *, | ||
276 | int)); | ||
277 | |||
278 | local void inflate_codes_free OF(( | ||
279 | inflate_codes_statef *, | ||
280 | z_stream *)); | ||
281 | |||
282 | |||
283 | /*+++++*/ | ||
284 | /* inflate.c -- zlib interface to inflate modules | ||
285 | * Copyright (C) 1995 Mark Adler | ||
286 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
287 | */ | ||
288 | |||
289 | /* inflate private state */ | ||
290 | struct internal_state { | ||
291 | |||
292 | /* mode */ | ||
293 | enum { | ||
294 | METHOD, /* waiting for method byte */ | ||
295 | FLAG, /* waiting for flag byte */ | ||
296 | BLOCKS, /* decompressing blocks */ | ||
297 | CHECK4, /* four check bytes to go */ | ||
298 | CHECK3, /* three check bytes to go */ | ||
299 | CHECK2, /* two check bytes to go */ | ||
300 | CHECK1, /* one check byte to go */ | ||
301 | DONE, /* finished check, done */ | ||
302 | BAD} /* got an error--stay here */ | ||
303 | mode; /* current inflate mode */ | ||
304 | |||
305 | /* mode dependent information */ | ||
306 | union { | ||
307 | uInt method; /* if FLAGS, method byte */ | ||
308 | struct { | ||
309 | uLong was; /* computed check value */ | ||
310 | uLong need; /* stream check value */ | ||
311 | } check; /* if CHECK, check values to compare */ | ||
312 | uInt marker; /* if BAD, inflateSync's marker bytes count */ | ||
313 | } sub; /* submode */ | ||
314 | |||
315 | /* mode independent information */ | ||
316 | int nowrap; /* flag for no wrapper */ | ||
317 | uInt wbits; /* log2(window size) (8..15, defaults to 15) */ | ||
318 | inflate_blocks_statef | ||
319 | *blocks; /* current inflate_blocks state */ | ||
320 | |||
321 | }; | ||
322 | |||
323 | |||
324 | int inflateReset( | ||
325 | z_stream *z | ||
326 | ) | ||
327 | { | ||
328 | uLong c; | ||
329 | |||
330 | if (z == Z_NULL || z->state == Z_NULL) | ||
331 | return Z_STREAM_ERROR; | ||
332 | z->total_in = z->total_out = 0; | ||
333 | z->msg = Z_NULL; | ||
334 | z->state->mode = z->state->nowrap ? BLOCKS : METHOD; | ||
335 | inflate_blocks_reset(z->state->blocks, z, &c); | ||
336 | Trace((stderr, "inflate: reset\n")); | ||
337 | return Z_OK; | ||
338 | } | ||
339 | |||
340 | |||
341 | int inflateEnd( | ||
342 | z_stream *z | ||
343 | ) | ||
344 | { | ||
345 | uLong c; | ||
346 | |||
347 | if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) | ||
348 | return Z_STREAM_ERROR; | ||
349 | if (z->state->blocks != Z_NULL) | ||
350 | inflate_blocks_free(z->state->blocks, z, &c); | ||
351 | ZFREE(z, z->state, sizeof(struct internal_state)); | ||
352 | z->state = Z_NULL; | ||
353 | Trace((stderr, "inflate: end\n")); | ||
354 | return Z_OK; | ||
355 | } | ||
356 | |||
357 | |||
358 | int inflateInit2( | ||
359 | z_stream *z, | ||
360 | int w | ||
361 | ) | ||
362 | { | ||
363 | /* initialize state */ | ||
364 | if (z == Z_NULL) | ||
365 | return Z_STREAM_ERROR; | ||
366 | /* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ | ||
367 | /* if (z->zfree == Z_NULL) z->zfree = zcfree; */ | ||
368 | if ((z->state = (struct internal_state FAR *) | ||
369 | ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) | ||
370 | return Z_MEM_ERROR; | ||
371 | z->state->blocks = Z_NULL; | ||
372 | |||
373 | /* handle undocumented nowrap option (no zlib header or check) */ | ||
374 | z->state->nowrap = 0; | ||
375 | if (w < 0) | ||
376 | { | ||
377 | w = - w; | ||
378 | z->state->nowrap = 1; | ||
379 | } | ||
380 | |||
381 | /* set window size */ | ||
382 | if (w < 8 || w > 15) | ||
383 | { | ||
384 | inflateEnd(z); | ||
385 | return Z_STREAM_ERROR; | ||
386 | } | ||
387 | z->state->wbits = (uInt)w; | ||
388 | |||
389 | /* create inflate_blocks state */ | ||
390 | if ((z->state->blocks = | ||
391 | inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) | ||
392 | == Z_NULL) | ||
393 | { | ||
394 | inflateEnd(z); | ||
395 | return Z_MEM_ERROR; | ||
396 | } | ||
397 | Trace((stderr, "inflate: allocated\n")); | ||
398 | |||
399 | /* reset state */ | ||
400 | inflateReset(z); | ||
401 | return Z_OK; | ||
402 | } | ||
403 | |||
404 | |||
405 | int inflateInit( | ||
406 | z_stream *z | ||
407 | ) | ||
408 | { | ||
409 | return inflateInit2(z, DEF_WBITS); | ||
410 | } | ||
411 | |||
412 | |||
413 | #define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} | ||
414 | #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) | ||
415 | |||
416 | int inflate( | ||
417 | z_stream *z, | ||
418 | int f | ||
419 | ) | ||
420 | { | ||
421 | int r; | ||
422 | uInt b; | ||
423 | |||
424 | if (z == Z_NULL || z->next_in == Z_NULL) | ||
425 | return Z_STREAM_ERROR; | ||
426 | r = Z_BUF_ERROR; | ||
427 | while (1) switch (z->state->mode) | ||
428 | { | ||
429 | case METHOD: | ||
430 | NEEDBYTE | ||
431 | if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) | ||
432 | { | ||
433 | z->state->mode = BAD; | ||
434 | z->msg = "unknown compression method"; | ||
435 | z->state->sub.marker = 5; /* can't try inflateSync */ | ||
436 | break; | ||
437 | } | ||
438 | if ((z->state->sub.method >> 4) + 8 > z->state->wbits) | ||
439 | { | ||
440 | z->state->mode = BAD; | ||
441 | z->msg = "invalid window size"; | ||
442 | z->state->sub.marker = 5; /* can't try inflateSync */ | ||
443 | break; | ||
444 | } | ||
445 | z->state->mode = FLAG; | ||
446 | case FLAG: | ||
447 | NEEDBYTE | ||
448 | if ((b = NEXTBYTE) & 0x20) | ||
449 | { | ||
450 | z->state->mode = BAD; | ||
451 | z->msg = "invalid reserved bit"; | ||
452 | z->state->sub.marker = 5; /* can't try inflateSync */ | ||
453 | break; | ||
454 | } | ||
455 | if (((z->state->sub.method << 8) + b) % 31) | ||
456 | { | ||
457 | z->state->mode = BAD; | ||
458 | z->msg = "incorrect header check"; | ||
459 | z->state->sub.marker = 5; /* can't try inflateSync */ | ||
460 | break; | ||
461 | } | ||
462 | Trace((stderr, "inflate: zlib header ok\n")); | ||
463 | z->state->mode = BLOCKS; | ||
464 | case BLOCKS: | ||
465 | r = inflate_blocks(z->state->blocks, z, r); | ||
466 | if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) | ||
467 | r = inflate_packet_flush(z->state->blocks); | ||
468 | if (r == Z_DATA_ERROR) | ||
469 | { | ||
470 | z->state->mode = BAD; | ||
471 | z->state->sub.marker = 0; /* can try inflateSync */ | ||
472 | break; | ||
473 | } | ||
474 | if (r != Z_STREAM_END) | ||
475 | return r; | ||
476 | r = Z_OK; | ||
477 | inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); | ||
478 | if (z->state->nowrap) | ||
479 | { | ||
480 | z->state->mode = DONE; | ||
481 | break; | ||
482 | } | ||
483 | z->state->mode = CHECK4; | ||
484 | case CHECK4: | ||
485 | NEEDBYTE | ||
486 | z->state->sub.check.need = (uLong)NEXTBYTE << 24; | ||
487 | z->state->mode = CHECK3; | ||
488 | case CHECK3: | ||
489 | NEEDBYTE | ||
490 | z->state->sub.check.need += (uLong)NEXTBYTE << 16; | ||
491 | z->state->mode = CHECK2; | ||
492 | case CHECK2: | ||
493 | NEEDBYTE | ||
494 | z->state->sub.check.need += (uLong)NEXTBYTE << 8; | ||
495 | z->state->mode = CHECK1; | ||
496 | case CHECK1: | ||
497 | NEEDBYTE | ||
498 | z->state->sub.check.need += (uLong)NEXTBYTE; | ||
499 | |||
500 | if (z->state->sub.check.was != z->state->sub.check.need) | ||
501 | { | ||
502 | z->state->mode = BAD; | ||
503 | z->msg = "incorrect data check"; | ||
504 | z->state->sub.marker = 5; /* can't try inflateSync */ | ||
505 | break; | ||
506 | } | ||
507 | Trace((stderr, "inflate: zlib check ok\n")); | ||
508 | z->state->mode = DONE; | ||
509 | case DONE: | ||
510 | return Z_STREAM_END; | ||
511 | case BAD: | ||
512 | return Z_DATA_ERROR; | ||
513 | default: | ||
514 | return Z_STREAM_ERROR; | ||
515 | } | ||
516 | |||
517 | empty: | ||
518 | if (f != Z_PACKET_FLUSH) | ||
519 | return r; | ||
520 | z->state->mode = BAD; | ||
521 | z->state->sub.marker = 0; /* can try inflateSync */ | ||
522 | return Z_DATA_ERROR; | ||
523 | } | ||
524 | |||
525 | /* | ||
526 | * This subroutine adds the data at next_in/avail_in to the output history | ||
527 | * without performing any output. The output buffer must be "caught up"; | ||
528 | * i.e. no pending output (hence s->read equals s->write), and the state must | ||
529 | * be BLOCKS (i.e. we should be willing to see the start of a series of | ||
530 | * BLOCKS). On exit, the output will also be caught up, and the checksum | ||
531 | * will have been updated if need be. | ||
532 | */ | ||
533 | |||
534 | int inflateIncomp( | ||
535 | z_stream *z | ||
536 | ) | ||
537 | { | ||
538 | if (z->state->mode != BLOCKS) | ||
539 | return Z_DATA_ERROR; | ||
540 | return inflate_addhistory(z->state->blocks, z); | ||
541 | } | ||
542 | |||
543 | |||
544 | int inflateSync( | ||
545 | z_stream *z | ||
546 | ) | ||
547 | { | ||
548 | uInt n; /* number of bytes to look at */ | ||
549 | Bytef *p; /* pointer to bytes */ | ||
550 | uInt m; /* number of marker bytes found in a row */ | ||
551 | uLong r, w; /* temporaries to save total_in and total_out */ | ||
552 | |||
553 | /* set up */ | ||
554 | if (z == Z_NULL || z->state == Z_NULL) | ||
555 | return Z_STREAM_ERROR; | ||
556 | if (z->state->mode != BAD) | ||
557 | { | ||
558 | z->state->mode = BAD; | ||
559 | z->state->sub.marker = 0; | ||
560 | } | ||
561 | if ((n = z->avail_in) == 0) | ||
562 | return Z_BUF_ERROR; | ||
563 | p = z->next_in; | ||
564 | m = z->state->sub.marker; | ||
565 | |||
566 | /* search */ | ||
567 | while (n && m < 4) | ||
568 | { | ||
569 | if (*p == (Byte)(m < 2 ? 0 : 0xff)) | ||
570 | m++; | ||
571 | else if (*p) | ||
572 | m = 0; | ||
573 | else | ||
574 | m = 4 - m; | ||
575 | p++, n--; | ||
576 | } | ||
577 | |||
578 | /* restore */ | ||
579 | z->total_in += p - z->next_in; | ||
580 | z->next_in = p; | ||
581 | z->avail_in = n; | ||
582 | z->state->sub.marker = m; | ||
583 | |||
584 | /* return no joy or set up to restart on a new block */ | ||
585 | if (m != 4) | ||
586 | return Z_DATA_ERROR; | ||
587 | r = z->total_in; w = z->total_out; | ||
588 | inflateReset(z); | ||
589 | z->total_in = r; z->total_out = w; | ||
590 | z->state->mode = BLOCKS; | ||
591 | return Z_OK; | ||
592 | } | ||
593 | |||
594 | #undef NEEDBYTE | ||
595 | #undef NEXTBYTE | ||
596 | |||
597 | /*+++++*/ | ||
598 | /* infutil.h -- types and macros common to blocks and codes | ||
599 | * Copyright (C) 1995 Mark Adler | ||
600 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
601 | */ | ||
602 | |||
603 | /* WARNING: this file should *not* be used by applications. It is | ||
604 | part of the implementation of the compression library and is | ||
605 | subject to change. Applications should only use zlib.h. | ||
606 | */ | ||
607 | |||
608 | /* inflate blocks semi-private state */ | ||
609 | struct inflate_blocks_state { | ||
610 | |||
611 | /* mode */ | ||
612 | enum { | ||
613 | TYPE, /* get type bits (3, including end bit) */ | ||
614 | LENS, /* get lengths for stored */ | ||
615 | STORED, /* processing stored block */ | ||
616 | TABLE, /* get table lengths */ | ||
617 | BTREE, /* get bit lengths tree for a dynamic block */ | ||
618 | DTREE, /* get length, distance trees for a dynamic block */ | ||
619 | CODES, /* processing fixed or dynamic block */ | ||
620 | DRY, /* output remaining window bytes */ | ||
621 | DONEB, /* finished last block, done */ | ||
622 | BADB} /* got a data error--stuck here */ | ||
623 | mode; /* current inflate_block mode */ | ||
624 | |||
625 | /* mode dependent information */ | ||
626 | union { | ||
627 | uInt left; /* if STORED, bytes left to copy */ | ||
628 | struct { | ||
629 | uInt table; /* table lengths (14 bits) */ | ||
630 | uInt index; /* index into blens (or border) */ | ||
631 | uIntf *blens; /* bit lengths of codes */ | ||
632 | uInt bb; /* bit length tree depth */ | ||
633 | inflate_huft *tb; /* bit length decoding tree */ | ||
634 | int nblens; /* # elements allocated at blens */ | ||
635 | } trees; /* if DTREE, decoding info for trees */ | ||
636 | struct { | ||
637 | inflate_huft *tl, *td; /* trees to free */ | ||
638 | inflate_codes_statef | ||
639 | *codes; | ||
640 | } decode; /* if CODES, current state */ | ||
641 | } sub; /* submode */ | ||
642 | uInt last; /* true if this block is the last block */ | ||
643 | |||
644 | /* mode independent information */ | ||
645 | uInt bitk; /* bits in bit buffer */ | ||
646 | uLong bitb; /* bit buffer */ | ||
647 | Bytef *window; /* sliding window */ | ||
648 | Bytef *end; /* one byte after sliding window */ | ||
649 | Bytef *read; /* window read pointer */ | ||
650 | Bytef *write; /* window write pointer */ | ||
651 | check_func checkfn; /* check function */ | ||
652 | uLong check; /* check on output */ | ||
653 | |||
654 | }; | ||
655 | |||
656 | |||
657 | /* defines for inflate input/output */ | ||
658 | /* update pointers and return */ | ||
659 | #define UPDBITS {s->bitb=b;s->bitk=k;} | ||
660 | #define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} | ||
661 | #define UPDOUT {s->write=q;} | ||
662 | #define UPDATE {UPDBITS UPDIN UPDOUT} | ||
663 | #define LEAVE {UPDATE return inflate_flush(s,z,r);} | ||
664 | /* get bytes and bits */ | ||
665 | #define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} | ||
666 | #define NEEDBYTE {if(n)r=Z_OK;else LEAVE} | ||
667 | #define NEXTBYTE (n--,*p++) | ||
668 | #define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} | ||
669 | #define DUMPBITS(j) {b>>=(j);k-=(j);} | ||
670 | /* output bytes */ | ||
671 | #define WAVAIL (q<s->read?s->read-q-1:s->end-q) | ||
672 | #define LOADOUT {q=s->write;m=WAVAIL;} | ||
673 | #define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} | ||
674 | #define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} | ||
675 | #define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} | ||
676 | #define OUTBYTE(a) {*q++=(Byte)(a);m--;} | ||
677 | /* load local pointers */ | ||
678 | #define LOAD {LOADIN LOADOUT} | ||
679 | |||
680 | /* And'ing with mask[n] masks the lower n bits */ | ||
681 | local uInt inflate_mask[] = { | ||
682 | 0x0000, | ||
683 | 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, | ||
684 | 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff | ||
685 | }; | ||
686 | |||
687 | /* copy as much as possible from the sliding window to the output area */ | ||
688 | local int inflate_flush OF(( | ||
689 | inflate_blocks_statef *, | ||
690 | z_stream *, | ||
691 | int)); | ||
692 | |||
693 | /*+++++*/ | ||
694 | /* inffast.h -- header to use inffast.c | ||
695 | * Copyright (C) 1995 Mark Adler | ||
696 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
697 | */ | ||
698 | |||
699 | /* WARNING: this file should *not* be used by applications. It is | ||
700 | part of the implementation of the compression library and is | ||
701 | subject to change. Applications should only use zlib.h. | ||
702 | */ | ||
703 | |||
704 | local int inflate_fast OF(( | ||
705 | uInt, | ||
706 | uInt, | ||
707 | inflate_huft *, | ||
708 | inflate_huft *, | ||
709 | inflate_blocks_statef *, | ||
710 | z_stream *)); | ||
711 | |||
712 | |||
713 | /*+++++*/ | ||
714 | /* infblock.c -- interpret and process block types to last block | ||
715 | * Copyright (C) 1995 Mark Adler | ||
716 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
717 | */ | ||
718 | |||
719 | /* Table for deflate from PKZIP's appnote.txt. */ | ||
720 | local uInt border[] = { /* Order of the bit length code lengths */ | ||
721 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; | ||
722 | |||
723 | /* | ||
724 | Notes beyond the 1.93a appnote.txt: | ||
725 | |||
726 | 1. Distance pointers never point before the beginning of the output | ||
727 | stream. | ||
728 | 2. Distance pointers can point back across blocks, up to 32k away. | ||
729 | 3. There is an implied maximum of 7 bits for the bit length table and | ||
730 | 15 bits for the actual data. | ||
731 | 4. If only one code exists, then it is encoded using one bit. (Zero | ||
732 | would be more efficient, but perhaps a little confusing.) If two | ||
733 | codes exist, they are coded using one bit each (0 and 1). | ||
734 | 5. There is no way of sending zero distance codes--a dummy must be | ||
735 | sent if there are none. (History: a pre 2.0 version of PKZIP would | ||
736 | store blocks with no distance codes, but this was discovered to be | ||
737 | too harsh a criterion.) Valid only for 1.93a. 2.04c does allow | ||
738 | zero distance codes, which is sent as one code of zero bits in | ||
739 | length. | ||
740 | 6. There are up to 286 literal/length codes. Code 256 represents the | ||
741 | end-of-block. Note however that the static length tree defines | ||
742 | 288 codes just to fill out the Huffman codes. Codes 286 and 287 | ||
743 | cannot be used though, since there is no length base or extra bits | ||
744 | defined for them. Similarily, there are up to 30 distance codes. | ||
745 | However, static trees define 32 codes (all 5 bits) to fill out the | ||
746 | Huffman codes, but the last two had better not show up in the data. | ||
747 | 7. Unzip can check dynamic Huffman blocks for complete code sets. | ||
748 | The exception is that a single code would not be complete (see #4). | ||
749 | 8. The five bits following the block type is really the number of | ||
750 | literal codes sent minus 257. | ||
751 | 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits | ||
752 | (1+6+6). Therefore, to output three times the length, you output | ||
753 | three codes (1+1+1), whereas to output four times the same length, | ||
754 | you only need two codes (1+3). Hmm. | ||
755 | 10. In the tree reconstruction algorithm, Code = Code + Increment | ||
756 | only if BitLength(i) is not zero. (Pretty obvious.) | ||
757 | 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) | ||
758 | 12. Note: length code 284 can represent 227-258, but length code 285 | ||
759 | really is 258. The last length deserves its own, short code | ||
760 | since it gets used a lot in very redundant files. The length | ||
761 | 258 is special since 258 - 3 (the min match length) is 255. | ||
762 | 13. The literal/length and distance code bit lengths are read as a | ||
763 | single stream of lengths. It is possible (and advantageous) for | ||
764 | a repeat code (16, 17, or 18) to go across the boundary between | ||
765 | the two sets of lengths. | ||
766 | */ | ||
767 | |||
768 | |||
769 | local void inflate_blocks_reset( | ||
770 | inflate_blocks_statef *s, | ||
771 | z_stream *z, | ||
772 | uLongf *c | ||
773 | ) | ||
774 | { | ||
775 | if (s->checkfn != Z_NULL) | ||
776 | *c = s->check; | ||
777 | if (s->mode == BTREE || s->mode == DTREE) | ||
778 | ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); | ||
779 | if (s->mode == CODES) | ||
780 | { | ||
781 | inflate_codes_free(s->sub.decode.codes, z); | ||
782 | inflate_trees_free(s->sub.decode.td, z); | ||
783 | inflate_trees_free(s->sub.decode.tl, z); | ||
784 | } | ||
785 | s->mode = TYPE; | ||
786 | s->bitk = 0; | ||
787 | s->bitb = 0; | ||
788 | s->read = s->write = s->window; | ||
789 | if (s->checkfn != Z_NULL) | ||
790 | s->check = (*s->checkfn)(0L, Z_NULL, 0); | ||
791 | Trace((stderr, "inflate: blocks reset\n")); | ||
792 | } | ||
793 | |||
794 | |||
795 | local inflate_blocks_statef *inflate_blocks_new( | ||
796 | z_stream *z, | ||
797 | check_func c, | ||
798 | uInt w | ||
799 | ) | ||
800 | { | ||
801 | inflate_blocks_statef *s; | ||
802 | |||
803 | if ((s = (inflate_blocks_statef *)ZALLOC | ||
804 | (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) | ||
805 | return s; | ||
806 | if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) | ||
807 | { | ||
808 | ZFREE(z, s, sizeof(struct inflate_blocks_state)); | ||
809 | return Z_NULL; | ||
810 | } | ||
811 | s->end = s->window + w; | ||
812 | s->checkfn = c; | ||
813 | s->mode = TYPE; | ||
814 | Trace((stderr, "inflate: blocks allocated\n")); | ||
815 | inflate_blocks_reset(s, z, &s->check); | ||
816 | return s; | ||
817 | } | ||
818 | |||
819 | |||
820 | local int inflate_blocks( | ||
821 | inflate_blocks_statef *s, | ||
822 | z_stream *z, | ||
823 | int r | ||
824 | ) | ||
825 | { | ||
826 | uInt t; /* temporary storage */ | ||
827 | uLong b; /* bit buffer */ | ||
828 | uInt k; /* bits in bit buffer */ | ||
829 | Bytef *p; /* input data pointer */ | ||
830 | uInt n; /* bytes available there */ | ||
831 | Bytef *q; /* output window write pointer */ | ||
832 | uInt m; /* bytes to end of window or read pointer */ | ||
833 | |||
834 | /* copy input/output information to locals (UPDATE macro restores) */ | ||
835 | LOAD | ||
836 | |||
837 | /* process input based on current state */ | ||
838 | while (1) switch (s->mode) | ||
839 | { | ||
840 | case TYPE: | ||
841 | NEEDBITS(3) | ||
842 | t = (uInt)b & 7; | ||
843 | s->last = t & 1; | ||
844 | switch (t >> 1) | ||
845 | { | ||
846 | case 0: /* stored */ | ||
847 | Trace((stderr, "inflate: stored block%s\n", | ||
848 | s->last ? " (last)" : "")); | ||
849 | DUMPBITS(3) | ||
850 | t = k & 7; /* go to byte boundary */ | ||
851 | DUMPBITS(t) | ||
852 | s->mode = LENS; /* get length of stored block */ | ||
853 | break; | ||
854 | case 1: /* fixed */ | ||
855 | Trace((stderr, "inflate: fixed codes block%s\n", | ||
856 | s->last ? " (last)" : "")); | ||
857 | { | ||
858 | uInt bl, bd; | ||
859 | inflate_huft *tl, *td; | ||
860 | |||
861 | inflate_trees_fixed(&bl, &bd, &tl, &td); | ||
862 | s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); | ||
863 | if (s->sub.decode.codes == Z_NULL) | ||
864 | { | ||
865 | r = Z_MEM_ERROR; | ||
866 | LEAVE | ||
867 | } | ||
868 | s->sub.decode.tl = Z_NULL; /* don't try to free these */ | ||
869 | s->sub.decode.td = Z_NULL; | ||
870 | } | ||
871 | DUMPBITS(3) | ||
872 | s->mode = CODES; | ||
873 | break; | ||
874 | case 2: /* dynamic */ | ||
875 | Trace((stderr, "inflate: dynamic codes block%s\n", | ||
876 | s->last ? " (last)" : "")); | ||
877 | DUMPBITS(3) | ||
878 | s->mode = TABLE; | ||
879 | break; | ||
880 | case 3: /* illegal */ | ||
881 | DUMPBITS(3) | ||
882 | s->mode = BADB; | ||
883 | z->msg = "invalid block type"; | ||
884 | r = Z_DATA_ERROR; | ||
885 | LEAVE | ||
886 | } | ||
887 | break; | ||
888 | case LENS: | ||
889 | NEEDBITS(32) | ||
890 | if (((~b) >> 16) != (b & 0xffff)) | ||
891 | { | ||
892 | s->mode = BADB; | ||
893 | z->msg = "invalid stored block lengths"; | ||
894 | r = Z_DATA_ERROR; | ||
895 | LEAVE | ||
896 | } | ||
897 | s->sub.left = (uInt)b & 0xffff; | ||
898 | b = k = 0; /* dump bits */ | ||
899 | Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); | ||
900 | s->mode = s->sub.left ? STORED : TYPE; | ||
901 | break; | ||
902 | case STORED: | ||
903 | if (n == 0) | ||
904 | LEAVE | ||
905 | NEEDOUT | ||
906 | t = s->sub.left; | ||
907 | if (t > n) t = n; | ||
908 | if (t > m) t = m; | ||
909 | zmemcpy(q, p, t); | ||
910 | p += t; n -= t; | ||
911 | q += t; m -= t; | ||
912 | if ((s->sub.left -= t) != 0) | ||
913 | break; | ||
914 | Tracev((stderr, "inflate: stored end, %lu total out\n", | ||
915 | z->total_out + (q >= s->read ? q - s->read : | ||
916 | (s->end - s->read) + (q - s->window)))); | ||
917 | s->mode = s->last ? DRY : TYPE; | ||
918 | break; | ||
919 | case TABLE: | ||
920 | NEEDBITS(14) | ||
921 | s->sub.trees.table = t = (uInt)b & 0x3fff; | ||
922 | #ifndef PKZIP_BUG_WORKAROUND | ||
923 | if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) | ||
924 | { | ||
925 | s->mode = BADB; | ||
926 | z->msg = "too many length or distance symbols"; | ||
927 | r = Z_DATA_ERROR; | ||
928 | LEAVE | ||
929 | } | ||
930 | #endif | ||
931 | t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); | ||
932 | if (t < 19) | ||
933 | t = 19; | ||
934 | if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) | ||
935 | { | ||
936 | r = Z_MEM_ERROR; | ||
937 | LEAVE | ||
938 | } | ||
939 | s->sub.trees.nblens = t; | ||
940 | DUMPBITS(14) | ||
941 | s->sub.trees.index = 0; | ||
942 | Tracev((stderr, "inflate: table sizes ok\n")); | ||
943 | s->mode = BTREE; | ||
944 | case BTREE: | ||
945 | while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) | ||
946 | { | ||
947 | NEEDBITS(3) | ||
948 | s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; | ||
949 | DUMPBITS(3) | ||
950 | } | ||
951 | while (s->sub.trees.index < 19) | ||
952 | s->sub.trees.blens[border[s->sub.trees.index++]] = 0; | ||
953 | s->sub.trees.bb = 7; | ||
954 | t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, | ||
955 | &s->sub.trees.tb, z); | ||
956 | if (t != Z_OK) | ||
957 | { | ||
958 | r = t; | ||
959 | if (r == Z_DATA_ERROR) | ||
960 | s->mode = BADB; | ||
961 | LEAVE | ||
962 | } | ||
963 | s->sub.trees.index = 0; | ||
964 | Tracev((stderr, "inflate: bits tree ok\n")); | ||
965 | s->mode = DTREE; | ||
966 | case DTREE: | ||
967 | while (t = s->sub.trees.table, | ||
968 | s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) | ||
969 | { | ||
970 | inflate_huft *h; | ||
971 | uInt i, j, c; | ||
972 | |||
973 | t = s->sub.trees.bb; | ||
974 | NEEDBITS(t) | ||
975 | h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); | ||
976 | t = h->word.what.Bits; | ||
977 | c = h->more.Base; | ||
978 | if (c < 16) | ||
979 | { | ||
980 | DUMPBITS(t) | ||
981 | s->sub.trees.blens[s->sub.trees.index++] = c; | ||
982 | } | ||
983 | else /* c == 16..18 */ | ||
984 | { | ||
985 | i = c == 18 ? 7 : c - 14; | ||
986 | j = c == 18 ? 11 : 3; | ||
987 | NEEDBITS(t + i) | ||
988 | DUMPBITS(t) | ||
989 | j += (uInt)b & inflate_mask[i]; | ||
990 | DUMPBITS(i) | ||
991 | i = s->sub.trees.index; | ||
992 | t = s->sub.trees.table; | ||
993 | if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || | ||
994 | (c == 16 && i < 1)) | ||
995 | { | ||
996 | s->mode = BADB; | ||
997 | z->msg = "invalid bit length repeat"; | ||
998 | r = Z_DATA_ERROR; | ||
999 | LEAVE | ||
1000 | } | ||
1001 | c = c == 16 ? s->sub.trees.blens[i - 1] : 0; | ||
1002 | do { | ||
1003 | s->sub.trees.blens[i++] = c; | ||
1004 | } while (--j); | ||
1005 | s->sub.trees.index = i; | ||
1006 | } | ||
1007 | } | ||
1008 | inflate_trees_free(s->sub.trees.tb, z); | ||
1009 | s->sub.trees.tb = Z_NULL; | ||
1010 | { | ||
1011 | uInt bl, bd; | ||
1012 | inflate_huft *tl, *td; | ||
1013 | inflate_codes_statef *c; | ||
1014 | |||
1015 | bl = 9; /* must be <= 9 for lookahead assumptions */ | ||
1016 | bd = 6; /* must be <= 9 for lookahead assumptions */ | ||
1017 | t = s->sub.trees.table; | ||
1018 | t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), | ||
1019 | s->sub.trees.blens, &bl, &bd, &tl, &td, z); | ||
1020 | if (t != Z_OK) | ||
1021 | { | ||
1022 | if (t == (uInt)Z_DATA_ERROR) | ||
1023 | s->mode = BADB; | ||
1024 | r = t; | ||
1025 | LEAVE | ||
1026 | } | ||
1027 | Tracev((stderr, "inflate: trees ok\n")); | ||
1028 | if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) | ||
1029 | { | ||
1030 | inflate_trees_free(td, z); | ||
1031 | inflate_trees_free(tl, z); | ||
1032 | r = Z_MEM_ERROR; | ||
1033 | LEAVE | ||
1034 | } | ||
1035 | ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); | ||
1036 | s->sub.decode.codes = c; | ||
1037 | s->sub.decode.tl = tl; | ||
1038 | s->sub.decode.td = td; | ||
1039 | } | ||
1040 | s->mode = CODES; | ||
1041 | case CODES: | ||
1042 | UPDATE | ||
1043 | if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) | ||
1044 | return inflate_flush(s, z, r); | ||
1045 | r = Z_OK; | ||
1046 | inflate_codes_free(s->sub.decode.codes, z); | ||
1047 | inflate_trees_free(s->sub.decode.td, z); | ||
1048 | inflate_trees_free(s->sub.decode.tl, z); | ||
1049 | LOAD | ||
1050 | Tracev((stderr, "inflate: codes end, %lu total out\n", | ||
1051 | z->total_out + (q >= s->read ? q - s->read : | ||
1052 | (s->end - s->read) + (q - s->window)))); | ||
1053 | if (!s->last) | ||
1054 | { | ||
1055 | s->mode = TYPE; | ||
1056 | break; | ||
1057 | } | ||
1058 | if (k > 7) /* return unused byte, if any */ | ||
1059 | { | ||
1060 | Assert(k < 16, "inflate_codes grabbed too many bytes") | ||
1061 | k -= 8; | ||
1062 | n++; | ||
1063 | p--; /* can always return one */ | ||
1064 | } | ||
1065 | s->mode = DRY; | ||
1066 | case DRY: | ||
1067 | FLUSH | ||
1068 | if (s->read != s->write) | ||
1069 | LEAVE | ||
1070 | s->mode = DONEB; | ||
1071 | case DONEB: | ||
1072 | r = Z_STREAM_END; | ||
1073 | LEAVE | ||
1074 | case BADB: | ||
1075 | r = Z_DATA_ERROR; | ||
1076 | LEAVE | ||
1077 | default: | ||
1078 | r = Z_STREAM_ERROR; | ||
1079 | LEAVE | ||
1080 | } | ||
1081 | } | ||
1082 | |||
1083 | |||
1084 | local int inflate_blocks_free( | ||
1085 | inflate_blocks_statef *s, | ||
1086 | z_stream *z, | ||
1087 | uLongf *c | ||
1088 | ) | ||
1089 | { | ||
1090 | inflate_blocks_reset(s, z, c); | ||
1091 | ZFREE(z, s->window, s->end - s->window); | ||
1092 | ZFREE(z, s, sizeof(struct inflate_blocks_state)); | ||
1093 | Trace((stderr, "inflate: blocks freed\n")); | ||
1094 | return Z_OK; | ||
1095 | } | ||
1096 | |||
1097 | /* | ||
1098 | * This subroutine adds the data at next_in/avail_in to the output history | ||
1099 | * without performing any output. The output buffer must be "caught up"; | ||
1100 | * i.e. no pending output (hence s->read equals s->write), and the state must | ||
1101 | * be BLOCKS (i.e. we should be willing to see the start of a series of | ||
1102 | * BLOCKS). On exit, the output will also be caught up, and the checksum | ||
1103 | * will have been updated if need be. | ||
1104 | */ | ||
1105 | local int inflate_addhistory( | ||
1106 | inflate_blocks_statef *s, | ||
1107 | z_stream *z | ||
1108 | ) | ||
1109 | { | ||
1110 | uLong b; /* bit buffer */ /* NOT USED HERE */ | ||
1111 | uInt k; /* bits in bit buffer */ /* NOT USED HERE */ | ||
1112 | uInt t; /* temporary storage */ | ||
1113 | Bytef *p; /* input data pointer */ | ||
1114 | uInt n; /* bytes available there */ | ||
1115 | Bytef *q; /* output window write pointer */ | ||
1116 | uInt m; /* bytes to end of window or read pointer */ | ||
1117 | |||
1118 | if (s->read != s->write) | ||
1119 | return Z_STREAM_ERROR; | ||
1120 | if (s->mode != TYPE) | ||
1121 | return Z_DATA_ERROR; | ||
1122 | |||
1123 | /* we're ready to rock */ | ||
1124 | LOAD | ||
1125 | /* while there is input ready, copy to output buffer, moving | ||
1126 | * pointers as needed. | ||
1127 | */ | ||
1128 | while (n) { | ||
1129 | t = n; /* how many to do */ | ||
1130 | /* is there room until end of buffer? */ | ||
1131 | if (t > m) t = m; | ||
1132 | /* update check information */ | ||
1133 | if (s->checkfn != Z_NULL) | ||
1134 | s->check = (*s->checkfn)(s->check, q, t); | ||
1135 | zmemcpy(q, p, t); | ||
1136 | q += t; | ||
1137 | p += t; | ||
1138 | n -= t; | ||
1139 | z->total_out += t; | ||
1140 | s->read = q; /* drag read pointer forward */ | ||
1141 | /* WRAP */ /* expand WRAP macro by hand to handle s->read */ | ||
1142 | if (q == s->end) { | ||
1143 | s->read = q = s->window; | ||
1144 | m = WAVAIL; | ||
1145 | } | ||
1146 | } | ||
1147 | UPDATE | ||
1148 | return Z_OK; | ||
1149 | } | ||
1150 | |||
1151 | |||
1152 | /* | ||
1153 | * At the end of a Deflate-compressed PPP packet, we expect to have seen | ||
1154 | * a `stored' block type value but not the (zero) length bytes. | ||
1155 | */ | ||
1156 | local int inflate_packet_flush( | ||
1157 | inflate_blocks_statef *s | ||
1158 | ) | ||
1159 | { | ||
1160 | if (s->mode != LENS) | ||
1161 | return Z_DATA_ERROR; | ||
1162 | s->mode = TYPE; | ||
1163 | return Z_OK; | ||
1164 | } | ||
1165 | |||
1166 | |||
1167 | /*+++++*/ | ||
1168 | /* inftrees.c -- generate Huffman trees for efficient decoding | ||
1169 | * Copyright (C) 1995 Mark Adler | ||
1170 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
1171 | */ | ||
1172 | |||
1173 | /* simplify the use of the inflate_huft type with some defines */ | ||
1174 | #define base more.Base | ||
1175 | #define next more.Next | ||
1176 | #define exop word.what.Exop | ||
1177 | #define bits word.what.Bits | ||
1178 | |||
1179 | |||
1180 | local int huft_build OF(( | ||
1181 | uIntf *, /* code lengths in bits */ | ||
1182 | uInt, /* number of codes */ | ||
1183 | uInt, /* number of "simple" codes */ | ||
1184 | uIntf *, /* list of base values for non-simple codes */ | ||
1185 | uIntf *, /* list of extra bits for non-simple codes */ | ||
1186 | inflate_huft * FAR*,/* result: starting table */ | ||
1187 | uIntf *, /* maximum lookup bits (returns actual) */ | ||
1188 | z_stream *)); /* for zalloc function */ | ||
1189 | |||
1190 | local voidpf falloc OF(( | ||
1191 | voidpf, /* opaque pointer (not used) */ | ||
1192 | uInt, /* number of items */ | ||
1193 | uInt)); /* size of item */ | ||
1194 | |||
1195 | local void ffree OF(( | ||
1196 | voidpf q, /* opaque pointer (not used) */ | ||
1197 | voidpf p, /* what to free (not used) */ | ||
1198 | uInt n)); /* number of bytes (not used) */ | ||
1199 | |||
1200 | /* Tables for deflate from PKZIP's appnote.txt. */ | ||
1201 | local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ | ||
1202 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, | ||
1203 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; | ||
1204 | /* actually lengths - 2; also see note #13 above about 258 */ | ||
1205 | local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ | ||
1206 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, | ||
1207 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ | ||
1208 | local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ | ||
1209 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, | ||
1210 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, | ||
1211 | 8193, 12289, 16385, 24577}; | ||
1212 | local uInt cpdext[] = { /* Extra bits for distance codes */ | ||
1213 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, | ||
1214 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, | ||
1215 | 12, 12, 13, 13}; | ||
1216 | |||
1217 | /* | ||
1218 | Huffman code decoding is performed using a multi-level table lookup. | ||
1219 | The fastest way to decode is to simply build a lookup table whose | ||
1220 | size is determined by the longest code. However, the time it takes | ||
1221 | to build this table can also be a factor if the data being decoded | ||
1222 | is not very long. The most common codes are necessarily the | ||
1223 | shortest codes, so those codes dominate the decoding time, and hence | ||
1224 | the speed. The idea is you can have a shorter table that decodes the | ||
1225 | shorter, more probable codes, and then point to subsidiary tables for | ||
1226 | the longer codes. The time it costs to decode the longer codes is | ||
1227 | then traded against the time it takes to make longer tables. | ||
1228 | |||
1229 | This results of this trade are in the variables lbits and dbits | ||
1230 | below. lbits is the number of bits the first level table for literal/ | ||
1231 | length codes can decode in one step, and dbits is the same thing for | ||
1232 | the distance codes. Subsequent tables are also less than or equal to | ||
1233 | those sizes. These values may be adjusted either when all of the | ||
1234 | codes are shorter than that, in which case the longest code length in | ||
1235 | bits is used, or when the shortest code is *longer* than the requested | ||
1236 | table size, in which case the length of the shortest code in bits is | ||
1237 | used. | ||
1238 | |||
1239 | There are two different values for the two tables, since they code a | ||
1240 | different number of possibilities each. The literal/length table | ||
1241 | codes 286 possible values, or in a flat code, a little over eight | ||
1242 | bits. The distance table codes 30 possible values, or a little less | ||
1243 | than five bits, flat. The optimum values for speed end up being | ||
1244 | about one bit more than those, so lbits is 8+1 and dbits is 5+1. | ||
1245 | The optimum values may differ though from machine to machine, and | ||
1246 | possibly even between compilers. Your mileage may vary. | ||
1247 | */ | ||
1248 | |||
1249 | |||
1250 | /* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ | ||
1251 | #define BMAX 15 /* maximum bit length of any code */ | ||
1252 | #define N_MAX 288 /* maximum number of codes in any set */ | ||
1253 | |||
1254 | #ifdef DEBUG_ZLIB | ||
1255 | uInt inflate_hufts; | ||
1256 | #endif | ||
1257 | |||
1258 | local int huft_build( | ||
1259 | uIntf *b, /* code lengths in bits (all assumed <= BMAX) */ | ||
1260 | uInt n, /* number of codes (assumed <= N_MAX) */ | ||
1261 | uInt s, /* number of simple-valued codes (0..s-1) */ | ||
1262 | uIntf *d, /* list of base values for non-simple codes */ | ||
1263 | uIntf *e, /* list of extra bits for non-simple codes */ | ||
1264 | inflate_huft * FAR *t, /* result: starting table */ | ||
1265 | uIntf *m, /* maximum lookup bits, returns actual */ | ||
1266 | z_stream *zs /* for zalloc function */ | ||
1267 | ) | ||
1268 | /* Given a list of code lengths and a maximum table size, make a set of | ||
1269 | tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR | ||
1270 | if the given code set is incomplete (the tables are still built in this | ||
1271 | case), Z_DATA_ERROR if the input is invalid (all zero length codes or an | ||
1272 | over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ | ||
1273 | { | ||
1274 | |||
1275 | uInt a; /* counter for codes of length k */ | ||
1276 | uInt c[BMAX+1]; /* bit length count table */ | ||
1277 | uInt f; /* i repeats in table every f entries */ | ||
1278 | int g; /* maximum code length */ | ||
1279 | int h; /* table level */ | ||
1280 | register uInt i; /* counter, current code */ | ||
1281 | register uInt j; /* counter */ | ||
1282 | register int k; /* number of bits in current code */ | ||
1283 | int l; /* bits per table (returned in m) */ | ||
1284 | register uIntf *p; /* pointer into c[], b[], or v[] */ | ||
1285 | inflate_huft *q; /* points to current table */ | ||
1286 | struct inflate_huft_s r; /* table entry for structure assignment */ | ||
1287 | inflate_huft *u[BMAX]; /* table stack */ | ||
1288 | uInt v[N_MAX]; /* values in order of bit length */ | ||
1289 | register int w; /* bits before this table == (l * h) */ | ||
1290 | uInt x[BMAX+1]; /* bit offsets, then code stack */ | ||
1291 | uIntf *xp; /* pointer into x */ | ||
1292 | int y; /* number of dummy codes added */ | ||
1293 | uInt z; /* number of entries in current table */ | ||
1294 | |||
1295 | |||
1296 | /* Generate counts for each bit length */ | ||
1297 | p = c; | ||
1298 | #define C0 *p++ = 0; | ||
1299 | #define C2 C0 C0 C0 C0 | ||
1300 | #define C4 C2 C2 C2 C2 | ||
1301 | C4 /* clear c[]--assume BMAX+1 is 16 */ | ||
1302 | p = b; i = n; | ||
1303 | do { | ||
1304 | c[*p++]++; /* assume all entries <= BMAX */ | ||
1305 | } while (--i); | ||
1306 | if (c[0] == n) /* null input--all zero length codes */ | ||
1307 | { | ||
1308 | *t = (inflate_huft *)Z_NULL; | ||
1309 | *m = 0; | ||
1310 | return Z_OK; | ||
1311 | } | ||
1312 | |||
1313 | |||
1314 | /* Find minimum and maximum length, bound *m by those */ | ||
1315 | l = *m; | ||
1316 | for (j = 1; j <= BMAX; j++) | ||
1317 | if (c[j]) | ||
1318 | break; | ||
1319 | k = j; /* minimum code length */ | ||
1320 | if ((uInt)l < j) | ||
1321 | l = j; | ||
1322 | for (i = BMAX; i; i--) | ||
1323 | if (c[i]) | ||
1324 | break; | ||
1325 | g = i; /* maximum code length */ | ||
1326 | if ((uInt)l > i) | ||
1327 | l = i; | ||
1328 | *m = l; | ||
1329 | |||
1330 | |||
1331 | /* Adjust last length count to fill out codes, if needed */ | ||
1332 | for (y = 1 << j; j < i; j++, y <<= 1) | ||
1333 | if ((y -= c[j]) < 0) | ||
1334 | return Z_DATA_ERROR; | ||
1335 | if ((y -= c[i]) < 0) | ||
1336 | return Z_DATA_ERROR; | ||
1337 | c[i] += y; | ||
1338 | |||
1339 | |||
1340 | /* Generate starting offsets into the value table for each length */ | ||
1341 | x[1] = j = 0; | ||
1342 | p = c + 1; xp = x + 2; | ||
1343 | while (--i) { /* note that i == g from above */ | ||
1344 | *xp++ = (j += *p++); | ||
1345 | } | ||
1346 | |||
1347 | |||
1348 | /* Make a table of values in order of bit lengths */ | ||
1349 | p = b; i = 0; | ||
1350 | do { | ||
1351 | if ((j = *p++) != 0) | ||
1352 | v[x[j]++] = i; | ||
1353 | } while (++i < n); | ||
1354 | |||
1355 | |||
1356 | /* Generate the Huffman codes and for each, make the table entries */ | ||
1357 | x[0] = i = 0; /* first Huffman code is zero */ | ||
1358 | p = v; /* grab values in bit order */ | ||
1359 | h = -1; /* no tables yet--level -1 */ | ||
1360 | w = -l; /* bits decoded == (l * h) */ | ||
1361 | u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ | ||
1362 | q = (inflate_huft *)Z_NULL; /* ditto */ | ||
1363 | z = 0; /* ditto */ | ||
1364 | |||
1365 | /* go through the bit lengths (k already is bits in shortest code) */ | ||
1366 | for (; k <= g; k++) | ||
1367 | { | ||
1368 | a = c[k]; | ||
1369 | while (a--) | ||
1370 | { | ||
1371 | /* here i is the Huffman code of length k bits for value *p */ | ||
1372 | /* make tables up to required level */ | ||
1373 | while (k > w + l) | ||
1374 | { | ||
1375 | h++; | ||
1376 | w += l; /* previous table always l bits */ | ||
1377 | |||
1378 | /* compute minimum size table less than or equal to l bits */ | ||
1379 | z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ | ||
1380 | if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ | ||
1381 | { /* too few codes for k-w bit table */ | ||
1382 | f -= a + 1; /* deduct codes from patterns left */ | ||
1383 | xp = c + k; | ||
1384 | if (j < z) | ||
1385 | while (++j < z) /* try smaller tables up to z bits */ | ||
1386 | { | ||
1387 | if ((f <<= 1) <= *++xp) | ||
1388 | break; /* enough codes to use up j bits */ | ||
1389 | f -= *xp; /* else deduct codes from patterns */ | ||
1390 | } | ||
1391 | } | ||
1392 | z = 1 << j; /* table entries for j-bit table */ | ||
1393 | |||
1394 | /* allocate and link in new table */ | ||
1395 | if ((q = (inflate_huft *)ZALLOC | ||
1396 | (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) | ||
1397 | { | ||
1398 | if (h) | ||
1399 | inflate_trees_free(u[0], zs); | ||
1400 | return Z_MEM_ERROR; /* not enough memory */ | ||
1401 | } | ||
1402 | q->word.Nalloc = z + 1; | ||
1403 | #ifdef DEBUG_ZLIB | ||
1404 | inflate_hufts += z + 1; | ||
1405 | #endif | ||
1406 | *t = q + 1; /* link to list for huft_free() */ | ||
1407 | *(t = &(q->next)) = Z_NULL; | ||
1408 | u[h] = ++q; /* table starts after link */ | ||
1409 | |||
1410 | /* connect to last table, if there is one */ | ||
1411 | if (h) | ||
1412 | { | ||
1413 | x[h] = i; /* save pattern for backing up */ | ||
1414 | r.bits = (Byte)l; /* bits to dump before this table */ | ||
1415 | r.exop = (Byte)j; /* bits in this table */ | ||
1416 | r.next = q; /* pointer to this table */ | ||
1417 | j = i >> (w - l); /* (get around Turbo C bug) */ | ||
1418 | u[h-1][j] = r; /* connect to last table */ | ||
1419 | } | ||
1420 | } | ||
1421 | |||
1422 | /* set up table entry in r */ | ||
1423 | r.bits = (Byte)(k - w); | ||
1424 | if (p >= v + n) | ||
1425 | r.exop = 128 + 64; /* out of values--invalid code */ | ||
1426 | else if (*p < s) | ||
1427 | { | ||
1428 | r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ | ||
1429 | r.base = *p++; /* simple code is just the value */ | ||
1430 | } | ||
1431 | else | ||
1432 | { | ||
1433 | r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ | ||
1434 | r.base = d[*p++ - s]; | ||
1435 | } | ||
1436 | |||
1437 | /* fill code-like entries with r */ | ||
1438 | f = 1 << (k - w); | ||
1439 | for (j = i >> w; j < z; j += f) | ||
1440 | q[j] = r; | ||
1441 | |||
1442 | /* backwards increment the k-bit code i */ | ||
1443 | for (j = 1 << (k - 1); i & j; j >>= 1) | ||
1444 | i ^= j; | ||
1445 | i ^= j; | ||
1446 | |||
1447 | /* backup over finished tables */ | ||
1448 | while ((i & ((1 << w) - 1)) != x[h]) | ||
1449 | { | ||
1450 | h--; /* don't need to update q */ | ||
1451 | w -= l; | ||
1452 | } | ||
1453 | } | ||
1454 | } | ||
1455 | |||
1456 | |||
1457 | /* Return Z_BUF_ERROR if we were given an incomplete table */ | ||
1458 | return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; | ||
1459 | } | ||
1460 | |||
1461 | |||
1462 | local int inflate_trees_bits( | ||
1463 | uIntf *c, /* 19 code lengths */ | ||
1464 | uIntf *bb, /* bits tree desired/actual depth */ | ||
1465 | inflate_huft * FAR *tb, /* bits tree result */ | ||
1466 | z_stream *z /* for zfree function */ | ||
1467 | ) | ||
1468 | { | ||
1469 | int r; | ||
1470 | |||
1471 | r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); | ||
1472 | if (r == Z_DATA_ERROR) | ||
1473 | z->msg = "oversubscribed dynamic bit lengths tree"; | ||
1474 | else if (r == Z_BUF_ERROR) | ||
1475 | { | ||
1476 | inflate_trees_free(*tb, z); | ||
1477 | z->msg = "incomplete dynamic bit lengths tree"; | ||
1478 | r = Z_DATA_ERROR; | ||
1479 | } | ||
1480 | return r; | ||
1481 | } | ||
1482 | |||
1483 | |||
1484 | local int inflate_trees_dynamic( | ||
1485 | uInt nl, /* number of literal/length codes */ | ||
1486 | uInt nd, /* number of distance codes */ | ||
1487 | uIntf *c, /* that many (total) code lengths */ | ||
1488 | uIntf *bl, /* literal desired/actual bit depth */ | ||
1489 | uIntf *bd, /* distance desired/actual bit depth */ | ||
1490 | inflate_huft * FAR *tl, /* literal/length tree result */ | ||
1491 | inflate_huft * FAR *td, /* distance tree result */ | ||
1492 | z_stream *z /* for zfree function */ | ||
1493 | ) | ||
1494 | { | ||
1495 | int r; | ||
1496 | |||
1497 | /* build literal/length tree */ | ||
1498 | if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) | ||
1499 | { | ||
1500 | if (r == Z_DATA_ERROR) | ||
1501 | z->msg = "oversubscribed literal/length tree"; | ||
1502 | else if (r == Z_BUF_ERROR) | ||
1503 | { | ||
1504 | inflate_trees_free(*tl, z); | ||
1505 | z->msg = "incomplete literal/length tree"; | ||
1506 | r = Z_DATA_ERROR; | ||
1507 | } | ||
1508 | return r; | ||
1509 | } | ||
1510 | |||
1511 | /* build distance tree */ | ||
1512 | if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) | ||
1513 | { | ||
1514 | if (r == Z_DATA_ERROR) | ||
1515 | z->msg = "oversubscribed literal/length tree"; | ||
1516 | else if (r == Z_BUF_ERROR) { | ||
1517 | #ifdef PKZIP_BUG_WORKAROUND | ||
1518 | r = Z_OK; | ||
1519 | } | ||
1520 | #else | ||
1521 | inflate_trees_free(*td, z); | ||
1522 | z->msg = "incomplete literal/length tree"; | ||
1523 | r = Z_DATA_ERROR; | ||
1524 | } | ||
1525 | inflate_trees_free(*tl, z); | ||
1526 | return r; | ||
1527 | #endif | ||
1528 | } | ||
1529 | |||
1530 | /* done */ | ||
1531 | return Z_OK; | ||
1532 | } | ||
1533 | |||
1534 | |||
1535 | /* build fixed tables only once--keep them here */ | ||
1536 | local int fixed_lock = 0; | ||
1537 | local int fixed_built = 0; | ||
1538 | #define FIXEDH 530 /* number of hufts used by fixed tables */ | ||
1539 | local uInt fixed_left = FIXEDH; | ||
1540 | local inflate_huft fixed_mem[FIXEDH]; | ||
1541 | local uInt fixed_bl; | ||
1542 | local uInt fixed_bd; | ||
1543 | local inflate_huft *fixed_tl; | ||
1544 | local inflate_huft *fixed_td; | ||
1545 | |||
1546 | |||
1547 | local voidpf falloc( | ||
1548 | voidpf q, /* opaque pointer (not used) */ | ||
1549 | uInt n, /* number of items */ | ||
1550 | uInt s /* size of item */ | ||
1551 | ) | ||
1552 | { | ||
1553 | Assert(s == sizeof(inflate_huft) && n <= fixed_left, | ||
1554 | "inflate_trees falloc overflow"); | ||
1555 | if (q) s++; /* to make some compilers happy */ | ||
1556 | fixed_left -= n; | ||
1557 | return (voidpf)(fixed_mem + fixed_left); | ||
1558 | } | ||
1559 | |||
1560 | |||
1561 | local void ffree( | ||
1562 | voidpf q, | ||
1563 | voidpf p, | ||
1564 | uInt n | ||
1565 | ) | ||
1566 | { | ||
1567 | Assert(0, "inflate_trees ffree called!"); | ||
1568 | if (q) q = p; /* to make some compilers happy */ | ||
1569 | } | ||
1570 | |||
1571 | |||
1572 | local int inflate_trees_fixed( | ||
1573 | uIntf *bl, /* literal desired/actual bit depth */ | ||
1574 | uIntf *bd, /* distance desired/actual bit depth */ | ||
1575 | inflate_huft * FAR *tl, /* literal/length tree result */ | ||
1576 | inflate_huft * FAR *td /* distance tree result */ | ||
1577 | ) | ||
1578 | { | ||
1579 | /* build fixed tables if not built already--lock out other instances */ | ||
1580 | while (++fixed_lock > 1) | ||
1581 | fixed_lock--; | ||
1582 | if (!fixed_built) | ||
1583 | { | ||
1584 | int k; /* temporary variable */ | ||
1585 | unsigned c[288]; /* length list for huft_build */ | ||
1586 | z_stream z; /* for falloc function */ | ||
1587 | |||
1588 | /* set up fake z_stream for memory routines */ | ||
1589 | z.zalloc = falloc; | ||
1590 | z.zfree = ffree; | ||
1591 | z.opaque = Z_NULL; | ||
1592 | |||
1593 | /* literal table */ | ||
1594 | for (k = 0; k < 144; k++) | ||
1595 | c[k] = 8; | ||
1596 | for (; k < 256; k++) | ||
1597 | c[k] = 9; | ||
1598 | for (; k < 280; k++) | ||
1599 | c[k] = 7; | ||
1600 | for (; k < 288; k++) | ||
1601 | c[k] = 8; | ||
1602 | fixed_bl = 7; | ||
1603 | huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); | ||
1604 | |||
1605 | /* distance table */ | ||
1606 | for (k = 0; k < 30; k++) | ||
1607 | c[k] = 5; | ||
1608 | fixed_bd = 5; | ||
1609 | huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); | ||
1610 | |||
1611 | /* done */ | ||
1612 | fixed_built = 1; | ||
1613 | } | ||
1614 | fixed_lock--; | ||
1615 | *bl = fixed_bl; | ||
1616 | *bd = fixed_bd; | ||
1617 | *tl = fixed_tl; | ||
1618 | *td = fixed_td; | ||
1619 | return Z_OK; | ||
1620 | } | ||
1621 | |||
1622 | |||
1623 | local int inflate_trees_free( | ||
1624 | inflate_huft *t, /* table to free */ | ||
1625 | z_stream *z /* for zfree function */ | ||
1626 | ) | ||
1627 | /* Free the malloc'ed tables built by huft_build(), which makes a linked | ||
1628 | list of the tables it made, with the links in a dummy first entry of | ||
1629 | each table. */ | ||
1630 | { | ||
1631 | register inflate_huft *p, *q; | ||
1632 | |||
1633 | /* Go through linked list, freeing from the malloced (t[-1]) address. */ | ||
1634 | p = t; | ||
1635 | while (p != Z_NULL) | ||
1636 | { | ||
1637 | q = (--p)->next; | ||
1638 | ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); | ||
1639 | p = q; | ||
1640 | } | ||
1641 | return Z_OK; | ||
1642 | } | ||
1643 | |||
1644 | /*+++++*/ | ||
1645 | /* infcodes.c -- process literals and length/distance pairs | ||
1646 | * Copyright (C) 1995 Mark Adler | ||
1647 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
1648 | */ | ||
1649 | |||
1650 | /* simplify the use of the inflate_huft type with some defines */ | ||
1651 | #define base more.Base | ||
1652 | #define next more.Next | ||
1653 | #define exop word.what.Exop | ||
1654 | #define bits word.what.Bits | ||
1655 | |||
1656 | /* inflate codes private state */ | ||
1657 | struct inflate_codes_state { | ||
1658 | |||
1659 | /* mode */ | ||
1660 | enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ | ||
1661 | START, /* x: set up for LEN */ | ||
1662 | LEN, /* i: get length/literal/eob next */ | ||
1663 | LENEXT, /* i: getting length extra (have base) */ | ||
1664 | DIST, /* i: get distance next */ | ||
1665 | DISTEXT, /* i: getting distance extra */ | ||
1666 | COPY, /* o: copying bytes in window, waiting for space */ | ||
1667 | LIT, /* o: got literal, waiting for output space */ | ||
1668 | WASH, /* o: got eob, possibly still output waiting */ | ||
1669 | END, /* x: got eob and all data flushed */ | ||
1670 | BADCODE} /* x: got error */ | ||
1671 | mode; /* current inflate_codes mode */ | ||
1672 | |||
1673 | /* mode dependent information */ | ||
1674 | uInt len; | ||
1675 | union { | ||
1676 | struct { | ||
1677 | inflate_huft *tree; /* pointer into tree */ | ||
1678 | uInt need; /* bits needed */ | ||
1679 | } code; /* if LEN or DIST, where in tree */ | ||
1680 | uInt lit; /* if LIT, literal */ | ||
1681 | struct { | ||
1682 | uInt get; /* bits to get for extra */ | ||
1683 | uInt dist; /* distance back to copy from */ | ||
1684 | } copy; /* if EXT or COPY, where and how much */ | ||
1685 | } sub; /* submode */ | ||
1686 | |||
1687 | /* mode independent information */ | ||
1688 | Byte lbits; /* ltree bits decoded per branch */ | ||
1689 | Byte dbits; /* dtree bits decoder per branch */ | ||
1690 | inflate_huft *ltree; /* literal/length/eob tree */ | ||
1691 | inflate_huft *dtree; /* distance tree */ | ||
1692 | |||
1693 | }; | ||
1694 | |||
1695 | |||
1696 | local inflate_codes_statef *inflate_codes_new( | ||
1697 | uInt bl, | ||
1698 | uInt bd, | ||
1699 | inflate_huft *tl, | ||
1700 | inflate_huft *td, | ||
1701 | z_stream *z | ||
1702 | ) | ||
1703 | { | ||
1704 | inflate_codes_statef *c; | ||
1705 | |||
1706 | if ((c = (inflate_codes_statef *) | ||
1707 | ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) | ||
1708 | { | ||
1709 | c->mode = START; | ||
1710 | c->lbits = (Byte)bl; | ||
1711 | c->dbits = (Byte)bd; | ||
1712 | c->ltree = tl; | ||
1713 | c->dtree = td; | ||
1714 | Tracev((stderr, "inflate: codes new\n")); | ||
1715 | } | ||
1716 | return c; | ||
1717 | } | ||
1718 | |||
1719 | |||
1720 | local int inflate_codes( | ||
1721 | inflate_blocks_statef *s, | ||
1722 | z_stream *z, | ||
1723 | int r | ||
1724 | ) | ||
1725 | { | ||
1726 | uInt j; /* temporary storage */ | ||
1727 | inflate_huft *t; /* temporary pointer */ | ||
1728 | uInt e; /* extra bits or operation */ | ||
1729 | uLong b; /* bit buffer */ | ||
1730 | uInt k; /* bits in bit buffer */ | ||
1731 | Bytef *p; /* input data pointer */ | ||
1732 | uInt n; /* bytes available there */ | ||
1733 | Bytef *q; /* output window write pointer */ | ||
1734 | uInt m; /* bytes to end of window or read pointer */ | ||
1735 | Bytef *f; /* pointer to copy strings from */ | ||
1736 | inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ | ||
1737 | |||
1738 | /* copy input/output information to locals (UPDATE macro restores) */ | ||
1739 | LOAD | ||
1740 | |||
1741 | /* process input and output based on current state */ | ||
1742 | while (1) switch (c->mode) | ||
1743 | { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ | ||
1744 | case START: /* x: set up for LEN */ | ||
1745 | #ifndef SLOW | ||
1746 | if (m >= 258 && n >= 10) | ||
1747 | { | ||
1748 | UPDATE | ||
1749 | r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); | ||
1750 | LOAD | ||
1751 | if (r != Z_OK) | ||
1752 | { | ||
1753 | c->mode = r == Z_STREAM_END ? WASH : BADCODE; | ||
1754 | break; | ||
1755 | } | ||
1756 | } | ||
1757 | #endif /* !SLOW */ | ||
1758 | c->sub.code.need = c->lbits; | ||
1759 | c->sub.code.tree = c->ltree; | ||
1760 | c->mode = LEN; | ||
1761 | case LEN: /* i: get length/literal/eob next */ | ||
1762 | j = c->sub.code.need; | ||
1763 | NEEDBITS(j) | ||
1764 | t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); | ||
1765 | DUMPBITS(t->bits) | ||
1766 | e = (uInt)(t->exop); | ||
1767 | if (e == 0) /* literal */ | ||
1768 | { | ||
1769 | c->sub.lit = t->base; | ||
1770 | Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? | ||
1771 | "inflate: literal '%c'\n" : | ||
1772 | "inflate: literal 0x%02x\n", t->base)); | ||
1773 | c->mode = LIT; | ||
1774 | break; | ||
1775 | } | ||
1776 | if (e & 16) /* length */ | ||
1777 | { | ||
1778 | c->sub.copy.get = e & 15; | ||
1779 | c->len = t->base; | ||
1780 | c->mode = LENEXT; | ||
1781 | break; | ||
1782 | } | ||
1783 | if ((e & 64) == 0) /* next table */ | ||
1784 | { | ||
1785 | c->sub.code.need = e; | ||
1786 | c->sub.code.tree = t->next; | ||
1787 | break; | ||
1788 | } | ||
1789 | if (e & 32) /* end of block */ | ||
1790 | { | ||
1791 | Tracevv((stderr, "inflate: end of block\n")); | ||
1792 | c->mode = WASH; | ||
1793 | break; | ||
1794 | } | ||
1795 | c->mode = BADCODE; /* invalid code */ | ||
1796 | z->msg = "invalid literal/length code"; | ||
1797 | r = Z_DATA_ERROR; | ||
1798 | LEAVE | ||
1799 | case LENEXT: /* i: getting length extra (have base) */ | ||
1800 | j = c->sub.copy.get; | ||
1801 | NEEDBITS(j) | ||
1802 | c->len += (uInt)b & inflate_mask[j]; | ||
1803 | DUMPBITS(j) | ||
1804 | c->sub.code.need = c->dbits; | ||
1805 | c->sub.code.tree = c->dtree; | ||
1806 | Tracevv((stderr, "inflate: length %u\n", c->len)); | ||
1807 | c->mode = DIST; | ||
1808 | case DIST: /* i: get distance next */ | ||
1809 | j = c->sub.code.need; | ||
1810 | NEEDBITS(j) | ||
1811 | t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); | ||
1812 | DUMPBITS(t->bits) | ||
1813 | e = (uInt)(t->exop); | ||
1814 | if (e & 16) /* distance */ | ||
1815 | { | ||
1816 | c->sub.copy.get = e & 15; | ||
1817 | c->sub.copy.dist = t->base; | ||
1818 | c->mode = DISTEXT; | ||
1819 | break; | ||
1820 | } | ||
1821 | if ((e & 64) == 0) /* next table */ | ||
1822 | { | ||
1823 | c->sub.code.need = e; | ||
1824 | c->sub.code.tree = t->next; | ||
1825 | break; | ||
1826 | } | ||
1827 | c->mode = BADCODE; /* invalid code */ | ||
1828 | z->msg = "invalid distance code"; | ||
1829 | r = Z_DATA_ERROR; | ||
1830 | LEAVE | ||
1831 | case DISTEXT: /* i: getting distance extra */ | ||
1832 | j = c->sub.copy.get; | ||
1833 | NEEDBITS(j) | ||
1834 | c->sub.copy.dist += (uInt)b & inflate_mask[j]; | ||
1835 | DUMPBITS(j) | ||
1836 | Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); | ||
1837 | c->mode = COPY; | ||
1838 | case COPY: /* o: copying bytes in window, waiting for space */ | ||
1839 | #ifndef __TURBOC__ /* Turbo C bug for following expression */ | ||
1840 | f = (uInt)(q - s->window) < c->sub.copy.dist ? | ||
1841 | s->end - (c->sub.copy.dist - (q - s->window)) : | ||
1842 | q - c->sub.copy.dist; | ||
1843 | #else | ||
1844 | f = q - c->sub.copy.dist; | ||
1845 | if ((uInt)(q - s->window) < c->sub.copy.dist) | ||
1846 | f = s->end - (c->sub.copy.dist - (q - s->window)); | ||
1847 | #endif | ||
1848 | while (c->len) | ||
1849 | { | ||
1850 | NEEDOUT | ||
1851 | OUTBYTE(*f++) | ||
1852 | if (f == s->end) | ||
1853 | f = s->window; | ||
1854 | c->len--; | ||
1855 | } | ||
1856 | c->mode = START; | ||
1857 | break; | ||
1858 | case LIT: /* o: got literal, waiting for output space */ | ||
1859 | NEEDOUT | ||
1860 | OUTBYTE(c->sub.lit) | ||
1861 | c->mode = START; | ||
1862 | break; | ||
1863 | case WASH: /* o: got eob, possibly more output */ | ||
1864 | FLUSH | ||
1865 | if (s->read != s->write) | ||
1866 | LEAVE | ||
1867 | c->mode = END; | ||
1868 | case END: | ||
1869 | r = Z_STREAM_END; | ||
1870 | LEAVE | ||
1871 | case BADCODE: /* x: got error */ | ||
1872 | r = Z_DATA_ERROR; | ||
1873 | LEAVE | ||
1874 | default: | ||
1875 | r = Z_STREAM_ERROR; | ||
1876 | LEAVE | ||
1877 | } | ||
1878 | } | ||
1879 | |||
1880 | |||
1881 | local void inflate_codes_free( | ||
1882 | inflate_codes_statef *c, | ||
1883 | z_stream *z | ||
1884 | ) | ||
1885 | { | ||
1886 | ZFREE(z, c, sizeof(struct inflate_codes_state)); | ||
1887 | Tracev((stderr, "inflate: codes free\n")); | ||
1888 | } | ||
1889 | |||
1890 | /*+++++*/ | ||
1891 | /* inflate_util.c -- data and routines common to blocks and codes | ||
1892 | * Copyright (C) 1995 Mark Adler | ||
1893 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
1894 | */ | ||
1895 | |||
1896 | /* copy as much as possible from the sliding window to the output area */ | ||
1897 | local int inflate_flush( | ||
1898 | inflate_blocks_statef *s, | ||
1899 | z_stream *z, | ||
1900 | int r | ||
1901 | ) | ||
1902 | { | ||
1903 | uInt n; | ||
1904 | Bytef *p, *q; | ||
1905 | |||
1906 | /* local copies of source and destination pointers */ | ||
1907 | p = z->next_out; | ||
1908 | q = s->read; | ||
1909 | |||
1910 | /* compute number of bytes to copy as far as end of window */ | ||
1911 | n = (uInt)((q <= s->write ? s->write : s->end) - q); | ||
1912 | if (n > z->avail_out) n = z->avail_out; | ||
1913 | if (n && r == Z_BUF_ERROR) r = Z_OK; | ||
1914 | |||
1915 | /* update counters */ | ||
1916 | z->avail_out -= n; | ||
1917 | z->total_out += n; | ||
1918 | |||
1919 | /* update check information */ | ||
1920 | if (s->checkfn != Z_NULL) | ||
1921 | s->check = (*s->checkfn)(s->check, q, n); | ||
1922 | |||
1923 | /* copy as far as end of window */ | ||
1924 | zmemcpy(p, q, n); | ||
1925 | p += n; | ||
1926 | q += n; | ||
1927 | |||
1928 | /* see if more to copy at beginning of window */ | ||
1929 | if (q == s->end) | ||
1930 | { | ||
1931 | /* wrap pointers */ | ||
1932 | q = s->window; | ||
1933 | if (s->write == s->end) | ||
1934 | s->write = s->window; | ||
1935 | |||
1936 | /* compute bytes to copy */ | ||
1937 | n = (uInt)(s->write - q); | ||
1938 | if (n > z->avail_out) n = z->avail_out; | ||
1939 | if (n && r == Z_BUF_ERROR) r = Z_OK; | ||
1940 | |||
1941 | /* update counters */ | ||
1942 | z->avail_out -= n; | ||
1943 | z->total_out += n; | ||
1944 | |||
1945 | /* update check information */ | ||
1946 | if (s->checkfn != Z_NULL) | ||
1947 | s->check = (*s->checkfn)(s->check, q, n); | ||
1948 | |||
1949 | /* copy */ | ||
1950 | zmemcpy(p, q, n); | ||
1951 | p += n; | ||
1952 | q += n; | ||
1953 | } | ||
1954 | |||
1955 | /* update pointers */ | ||
1956 | z->next_out = p; | ||
1957 | s->read = q; | ||
1958 | |||
1959 | /* done */ | ||
1960 | return r; | ||
1961 | } | ||
1962 | |||
1963 | |||
1964 | /*+++++*/ | ||
1965 | /* inffast.c -- process literals and length/distance pairs fast | ||
1966 | * Copyright (C) 1995 Mark Adler | ||
1967 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
1968 | */ | ||
1969 | |||
1970 | /* simplify the use of the inflate_huft type with some defines */ | ||
1971 | #define base more.Base | ||
1972 | #define next more.Next | ||
1973 | #define exop word.what.Exop | ||
1974 | #define bits word.what.Bits | ||
1975 | |||
1976 | /* macros for bit input with no checking and for returning unused bytes */ | ||
1977 | #define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} | ||
1978 | #define UNGRAB {n+=(c=k>>3);p-=c;k&=7;} | ||
1979 | |||
1980 | /* Called with number of bytes left to write in window at least 258 | ||
1981 | (the maximum string length) and number of input bytes available | ||
1982 | at least ten. The ten bytes are six bytes for the longest length/ | ||
1983 | distance pair plus four bytes for overloading the bit buffer. */ | ||
1984 | |||
1985 | local int inflate_fast( | ||
1986 | uInt bl, | ||
1987 | uInt bd, | ||
1988 | inflate_huft *tl, | ||
1989 | inflate_huft *td, | ||
1990 | inflate_blocks_statef *s, | ||
1991 | z_stream *z | ||
1992 | ) | ||
1993 | { | ||
1994 | inflate_huft *t; /* temporary pointer */ | ||
1995 | uInt e; /* extra bits or operation */ | ||
1996 | uLong b; /* bit buffer */ | ||
1997 | uInt k; /* bits in bit buffer */ | ||
1998 | Bytef *p; /* input data pointer */ | ||
1999 | uInt n; /* bytes available there */ | ||
2000 | Bytef *q; /* output window write pointer */ | ||
2001 | uInt m; /* bytes to end of window or read pointer */ | ||
2002 | uInt ml; /* mask for literal/length tree */ | ||
2003 | uInt md; /* mask for distance tree */ | ||
2004 | uInt c; /* bytes to copy */ | ||
2005 | uInt d; /* distance back to copy from */ | ||
2006 | Bytef *r; /* copy source pointer */ | ||
2007 | |||
2008 | /* load input, output, bit values */ | ||
2009 | LOAD | ||
2010 | |||
2011 | /* initialize masks */ | ||
2012 | ml = inflate_mask[bl]; | ||
2013 | md = inflate_mask[bd]; | ||
2014 | |||
2015 | /* do until not enough input or output space for fast loop */ | ||
2016 | do { /* assume called with m >= 258 && n >= 10 */ | ||
2017 | /* get literal/length code */ | ||
2018 | GRABBITS(20) /* max bits for literal/length code */ | ||
2019 | if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) | ||
2020 | { | ||
2021 | DUMPBITS(t->bits) | ||
2022 | Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? | ||
2023 | "inflate: * literal '%c'\n" : | ||
2024 | "inflate: * literal 0x%02x\n", t->base)); | ||
2025 | *q++ = (Byte)t->base; | ||
2026 | m--; | ||
2027 | continue; | ||
2028 | } | ||
2029 | do { | ||
2030 | DUMPBITS(t->bits) | ||
2031 | if (e & 16) | ||
2032 | { | ||
2033 | /* get extra bits for length */ | ||
2034 | e &= 15; | ||
2035 | c = t->base + ((uInt)b & inflate_mask[e]); | ||
2036 | DUMPBITS(e) | ||
2037 | Tracevv((stderr, "inflate: * length %u\n", c)); | ||
2038 | |||
2039 | /* decode distance base of block to copy */ | ||
2040 | GRABBITS(15); /* max bits for distance code */ | ||
2041 | e = (t = td + ((uInt)b & md))->exop; | ||
2042 | do { | ||
2043 | DUMPBITS(t->bits) | ||
2044 | if (e & 16) | ||
2045 | { | ||
2046 | /* get extra bits to add to distance base */ | ||
2047 | e &= 15; | ||
2048 | GRABBITS(e) /* get extra bits (up to 13) */ | ||
2049 | d = t->base + ((uInt)b & inflate_mask[e]); | ||
2050 | DUMPBITS(e) | ||
2051 | Tracevv((stderr, "inflate: * distance %u\n", d)); | ||
2052 | |||
2053 | /* do the copy */ | ||
2054 | m -= c; | ||
2055 | if ((uInt)(q - s->window) >= d) /* offset before dest */ | ||
2056 | { /* just copy */ | ||
2057 | r = q - d; | ||
2058 | *q++ = *r++; c--; /* minimum count is three, */ | ||
2059 | *q++ = *r++; c--; /* so unroll loop a little */ | ||
2060 | } | ||
2061 | else /* else offset after destination */ | ||
2062 | { | ||
2063 | e = d - (q - s->window); /* bytes from offset to end */ | ||
2064 | r = s->end - e; /* pointer to offset */ | ||
2065 | if (c > e) /* if source crosses, */ | ||
2066 | { | ||
2067 | c -= e; /* copy to end of window */ | ||
2068 | do { | ||
2069 | *q++ = *r++; | ||
2070 | } while (--e); | ||
2071 | r = s->window; /* copy rest from start of window */ | ||
2072 | } | ||
2073 | } | ||
2074 | do { /* copy all or what's left */ | ||
2075 | *q++ = *r++; | ||
2076 | } while (--c); | ||
2077 | break; | ||
2078 | } | ||
2079 | else if ((e & 64) == 0) | ||
2080 | e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; | ||
2081 | else | ||
2082 | { | ||
2083 | z->msg = "invalid distance code"; | ||
2084 | UNGRAB | ||
2085 | UPDATE | ||
2086 | return Z_DATA_ERROR; | ||
2087 | } | ||
2088 | } while (1); | ||
2089 | break; | ||
2090 | } | ||
2091 | if ((e & 64) == 0) | ||
2092 | { | ||
2093 | if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) | ||
2094 | { | ||
2095 | DUMPBITS(t->bits) | ||
2096 | Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? | ||
2097 | "inflate: * literal '%c'\n" : | ||
2098 | "inflate: * literal 0x%02x\n", t->base)); | ||
2099 | *q++ = (Byte)t->base; | ||
2100 | m--; | ||
2101 | break; | ||
2102 | } | ||
2103 | } | ||
2104 | else if (e & 32) | ||
2105 | { | ||
2106 | Tracevv((stderr, "inflate: * end of block\n")); | ||
2107 | UNGRAB | ||
2108 | UPDATE | ||
2109 | return Z_STREAM_END; | ||
2110 | } | ||
2111 | else | ||
2112 | { | ||
2113 | z->msg = "invalid literal/length code"; | ||
2114 | UNGRAB | ||
2115 | UPDATE | ||
2116 | return Z_DATA_ERROR; | ||
2117 | } | ||
2118 | } while (1); | ||
2119 | } while (m >= 258 && n >= 10); | ||
2120 | |||
2121 | /* not enough input or output--restore pointers and return */ | ||
2122 | UNGRAB | ||
2123 | UPDATE | ||
2124 | return Z_OK; | ||
2125 | } | ||
2126 | |||
2127 | |||
2128 | /*+++++*/ | ||
2129 | /* zutil.c -- target dependent utility functions for the compression library | ||
2130 | * Copyright (C) 1995 Jean-loup Gailly. | ||
2131 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
2132 | */ | ||
2133 | |||
2134 | /* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ | ||
2135 | |||
2136 | char *zlib_version = ZLIB_VERSION; | ||
2137 | |||
2138 | char *z_errmsg[] = { | ||
2139 | "stream end", /* Z_STREAM_END 1 */ | ||
2140 | "", /* Z_OK 0 */ | ||
2141 | "file error", /* Z_ERRNO (-1) */ | ||
2142 | "stream error", /* Z_STREAM_ERROR (-2) */ | ||
2143 | "data error", /* Z_DATA_ERROR (-3) */ | ||
2144 | "insufficient memory", /* Z_MEM_ERROR (-4) */ | ||
2145 | "buffer error", /* Z_BUF_ERROR (-5) */ | ||
2146 | ""}; | ||
2147 | |||
2148 | |||
2149 | /*+++++*/ | ||
2150 | /* adler32.c -- compute the Adler-32 checksum of a data stream | ||
2151 | * Copyright (C) 1995 Mark Adler | ||
2152 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
2153 | */ | ||
2154 | |||
2155 | /* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ | ||
2156 | |||
2157 | #define BASE 65521L /* largest prime smaller than 65536 */ | ||
2158 | #define NMAX 5552 | ||
2159 | /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ | ||
2160 | |||
2161 | #define DO1(buf) {s1 += *buf++; s2 += s1;} | ||
2162 | #define DO2(buf) DO1(buf); DO1(buf); | ||
2163 | #define DO4(buf) DO2(buf); DO2(buf); | ||
2164 | #define DO8(buf) DO4(buf); DO4(buf); | ||
2165 | #define DO16(buf) DO8(buf); DO8(buf); | ||
2166 | |||
2167 | /* ========================================================================= */ | ||
2168 | uLong adler32( | ||
2169 | uLong adler, | ||
2170 | Bytef *buf, | ||
2171 | uInt len | ||
2172 | ) | ||
2173 | { | ||
2174 | unsigned long s1 = adler & 0xffff; | ||
2175 | unsigned long s2 = (adler >> 16) & 0xffff; | ||
2176 | int k; | ||
2177 | |||
2178 | if (buf == Z_NULL) return 1L; | ||
2179 | |||
2180 | while (len > 0) { | ||
2181 | k = len < NMAX ? len : NMAX; | ||
2182 | len -= k; | ||
2183 | while (k >= 16) { | ||
2184 | DO16(buf); | ||
2185 | k -= 16; | ||
2186 | } | ||
2187 | if (k != 0) do { | ||
2188 | DO1(buf); | ||
2189 | } while (--k); | ||
2190 | s1 %= BASE; | ||
2191 | s2 %= BASE; | ||
2192 | } | ||
2193 | return (s2 << 16) | s1; | ||
2194 | } | ||
diff --git a/arch/ppc64/boot/zlib.h b/arch/ppc64/boot/zlib.h new file mode 100644 index 00000000000..f0b996c6864 --- /dev/null +++ b/arch/ppc64/boot/zlib.h | |||
@@ -0,0 +1,432 @@ | |||
1 | /* */ | ||
2 | |||
3 | /* | ||
4 | * This file is derived from zlib.h and zconf.h from the zlib-0.95 | ||
5 | * distribution by Jean-loup Gailly and Mark Adler, with some additions | ||
6 | * by Paul Mackerras to aid in implementing Deflate compression and | ||
7 | * decompression for PPP packets. | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * ==FILEVERSION 960122== | ||
12 | * | ||
13 | * This marker is used by the Linux installation script to determine | ||
14 | * whether an up-to-date version of this file is already installed. | ||
15 | */ | ||
16 | |||
17 | /* zlib.h -- interface of the 'zlib' general purpose compression library | ||
18 | version 0.95, Aug 16th, 1995. | ||
19 | |||
20 | Copyright (C) 1995 Jean-loup Gailly and Mark Adler | ||
21 | |||
22 | This software is provided 'as-is', without any express or implied | ||
23 | warranty. In no event will the authors be held liable for any damages | ||
24 | arising from the use of this software. | ||
25 | |||
26 | Permission is granted to anyone to use this software for any purpose, | ||
27 | including commercial applications, and to alter it and redistribute it | ||
28 | freely, subject to the following restrictions: | ||
29 | |||
30 | 1. The origin of this software must not be misrepresented; you must not | ||
31 | claim that you wrote the original software. If you use this software | ||
32 | in a product, an acknowledgment in the product documentation would be | ||
33 | appreciated but is not required. | ||
34 | 2. Altered source versions must be plainly marked as such, and must not be | ||
35 | misrepresented as being the original software. | ||
36 | 3. This notice may not be removed or altered from any source distribution. | ||
37 | |||
38 | Jean-loup Gailly Mark Adler | ||
39 | gzip@prep.ai.mit.edu madler@alumni.caltech.edu | ||
40 | */ | ||
41 | |||
42 | #ifndef _ZLIB_H | ||
43 | #define _ZLIB_H | ||
44 | |||
45 | /* #include "zconf.h" */ /* included directly here */ | ||
46 | |||
47 | /* zconf.h -- configuration of the zlib compression library | ||
48 | * Copyright (C) 1995 Jean-loup Gailly. | ||
49 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
50 | */ | ||
51 | |||
52 | /* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ | ||
53 | |||
54 | /* | ||
55 | The library does not install any signal handler. It is recommended to | ||
56 | add at least a handler for SIGSEGV when decompressing; the library checks | ||
57 | the consistency of the input data whenever possible but may go nuts | ||
58 | for some forms of corrupted input. | ||
59 | */ | ||
60 | |||
61 | /* | ||
62 | * Compile with -DMAXSEG_64K if the alloc function cannot allocate more | ||
63 | * than 64k bytes at a time (needed on systems with 16-bit int). | ||
64 | * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints | ||
65 | * at addresses which are not a multiple of their size. | ||
66 | * Under DOS, -DFAR=far or -DFAR=__far may be needed. | ||
67 | */ | ||
68 | |||
69 | #ifndef STDC | ||
70 | # if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) | ||
71 | # define STDC | ||
72 | # endif | ||
73 | #endif | ||
74 | |||
75 | #ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ | ||
76 | # include <unix.h> | ||
77 | #endif | ||
78 | |||
79 | /* Maximum value for memLevel in deflateInit2 */ | ||
80 | #ifndef MAX_MEM_LEVEL | ||
81 | # ifdef MAXSEG_64K | ||
82 | # define MAX_MEM_LEVEL 8 | ||
83 | # else | ||
84 | # define MAX_MEM_LEVEL 9 | ||
85 | # endif | ||
86 | #endif | ||
87 | |||
88 | #ifndef FAR | ||
89 | # define FAR | ||
90 | #endif | ||
91 | |||
92 | /* Maximum value for windowBits in deflateInit2 and inflateInit2 */ | ||
93 | #ifndef MAX_WBITS | ||
94 | # define MAX_WBITS 15 /* 32K LZ77 window */ | ||
95 | #endif | ||
96 | |||
97 | /* The memory requirements for deflate are (in bytes): | ||
98 | 1 << (windowBits+2) + 1 << (memLevel+9) | ||
99 | that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) | ||
100 | plus a few kilobytes for small objects. For example, if you want to reduce | ||
101 | the default memory requirements from 256K to 128K, compile with | ||
102 | make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" | ||
103 | Of course this will generally degrade compression (there's no free lunch). | ||
104 | |||
105 | The memory requirements for inflate are (in bytes) 1 << windowBits | ||
106 | that is, 32K for windowBits=15 (default value) plus a few kilobytes | ||
107 | for small objects. | ||
108 | */ | ||
109 | |||
110 | /* Type declarations */ | ||
111 | |||
112 | #ifndef OF /* function prototypes */ | ||
113 | # ifdef STDC | ||
114 | # define OF(args) args | ||
115 | # else | ||
116 | # define OF(args) () | ||
117 | # endif | ||
118 | #endif | ||
119 | |||
120 | typedef unsigned char Byte; /* 8 bits */ | ||
121 | typedef unsigned int uInt; /* 16 bits or more */ | ||
122 | typedef unsigned long uLong; /* 32 bits or more */ | ||
123 | |||
124 | typedef Byte FAR Bytef; | ||
125 | typedef char FAR charf; | ||
126 | typedef int FAR intf; | ||
127 | typedef uInt FAR uIntf; | ||
128 | typedef uLong FAR uLongf; | ||
129 | |||
130 | #ifdef STDC | ||
131 | typedef void FAR *voidpf; | ||
132 | typedef void *voidp; | ||
133 | #else | ||
134 | typedef Byte FAR *voidpf; | ||
135 | typedef Byte *voidp; | ||
136 | #endif | ||
137 | |||
138 | /* end of original zconf.h */ | ||
139 | |||
140 | #define ZLIB_VERSION "0.95P" | ||
141 | |||
142 | /* | ||
143 | The 'zlib' compression library provides in-memory compression and | ||
144 | decompression functions, including integrity checks of the uncompressed | ||
145 | data. This version of the library supports only one compression method | ||
146 | (deflation) but other algorithms may be added later and will have the same | ||
147 | stream interface. | ||
148 | |||
149 | For compression the application must provide the output buffer and | ||
150 | may optionally provide the input buffer for optimization. For decompression, | ||
151 | the application must provide the input buffer and may optionally provide | ||
152 | the output buffer for optimization. | ||
153 | |||
154 | Compression can be done in a single step if the buffers are large | ||
155 | enough (for example if an input file is mmap'ed), or can be done by | ||
156 | repeated calls of the compression function. In the latter case, the | ||
157 | application must provide more input and/or consume the output | ||
158 | (providing more output space) before each call. | ||
159 | */ | ||
160 | |||
161 | typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); | ||
162 | typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); | ||
163 | |||
164 | struct internal_state; | ||
165 | |||
166 | typedef struct z_stream_s { | ||
167 | Bytef *next_in; /* next input byte */ | ||
168 | uInt avail_in; /* number of bytes available at next_in */ | ||
169 | uLong total_in; /* total nb of input bytes read so far */ | ||
170 | |||
171 | Bytef *next_out; /* next output byte should be put there */ | ||
172 | uInt avail_out; /* remaining free space at next_out */ | ||
173 | uLong total_out; /* total nb of bytes output so far */ | ||
174 | |||
175 | char *msg; /* last error message, NULL if no error */ | ||
176 | struct internal_state FAR *state; /* not visible by applications */ | ||
177 | |||
178 | alloc_func zalloc; /* used to allocate the internal state */ | ||
179 | free_func zfree; /* used to free the internal state */ | ||
180 | voidp opaque; /* private data object passed to zalloc and zfree */ | ||
181 | |||
182 | Byte data_type; /* best guess about the data type: ascii or binary */ | ||
183 | |||
184 | } z_stream; | ||
185 | |||
186 | /* | ||
187 | The application must update next_in and avail_in when avail_in has | ||
188 | dropped to zero. It must update next_out and avail_out when avail_out | ||
189 | has dropped to zero. The application must initialize zalloc, zfree and | ||
190 | opaque before calling the init function. All other fields are set by the | ||
191 | compression library and must not be updated by the application. | ||
192 | |||
193 | The opaque value provided by the application will be passed as the first | ||
194 | parameter for calls of zalloc and zfree. This can be useful for custom | ||
195 | memory management. The compression library attaches no meaning to the | ||
196 | opaque value. | ||
197 | |||
198 | zalloc must return Z_NULL if there is not enough memory for the object. | ||
199 | On 16-bit systems, the functions zalloc and zfree must be able to allocate | ||
200 | exactly 65536 bytes, but will not be required to allocate more than this | ||
201 | if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, | ||
202 | pointers returned by zalloc for objects of exactly 65536 bytes *must* | ||
203 | have their offset normalized to zero. The default allocation function | ||
204 | provided by this library ensures this (see zutil.c). To reduce memory | ||
205 | requirements and avoid any allocation of 64K objects, at the expense of | ||
206 | compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). | ||
207 | |||
208 | The fields total_in and total_out can be used for statistics or | ||
209 | progress reports. After compression, total_in holds the total size of | ||
210 | the uncompressed data and may be saved for use in the decompressor | ||
211 | (particularly if the decompressor wants to decompress everything in | ||
212 | a single step). | ||
213 | */ | ||
214 | |||
215 | /* constants */ | ||
216 | |||
217 | #define Z_NO_FLUSH 0 | ||
218 | #define Z_PARTIAL_FLUSH 1 | ||
219 | #define Z_FULL_FLUSH 2 | ||
220 | #define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ | ||
221 | #define Z_FINISH 4 | ||
222 | #define Z_PACKET_FLUSH 5 | ||
223 | /* See deflate() below for the usage of these constants */ | ||
224 | |||
225 | #define Z_OK 0 | ||
226 | #define Z_STREAM_END 1 | ||
227 | #define Z_ERRNO (-1) | ||
228 | #define Z_STREAM_ERROR (-2) | ||
229 | #define Z_DATA_ERROR (-3) | ||
230 | #define Z_MEM_ERROR (-4) | ||
231 | #define Z_BUF_ERROR (-5) | ||
232 | /* error codes for the compression/decompression functions */ | ||
233 | |||
234 | #define Z_BEST_SPEED 1 | ||
235 | #define Z_BEST_COMPRESSION 9 | ||
236 | #define Z_DEFAULT_COMPRESSION (-1) | ||
237 | /* compression levels */ | ||
238 | |||
239 | #define Z_FILTERED 1 | ||
240 | #define Z_HUFFMAN_ONLY 2 | ||
241 | #define Z_DEFAULT_STRATEGY 0 | ||
242 | |||
243 | #define Z_BINARY 0 | ||
244 | #define Z_ASCII 1 | ||
245 | #define Z_UNKNOWN 2 | ||
246 | /* Used to set the data_type field */ | ||
247 | |||
248 | #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ | ||
249 | |||
250 | extern char *zlib_version; | ||
251 | /* The application can compare zlib_version and ZLIB_VERSION for consistency. | ||
252 | If the first character differs, the library code actually used is | ||
253 | not compatible with the zlib.h header file used by the application. | ||
254 | */ | ||
255 | |||
256 | /* basic functions */ | ||
257 | |||
258 | extern int inflateInit OF((z_stream *strm)); | ||
259 | /* | ||
260 | Initializes the internal stream state for decompression. The fields | ||
261 | zalloc and zfree must be initialized before by the caller. If zalloc and | ||
262 | zfree are set to Z_NULL, inflateInit updates them to use default allocation | ||
263 | functions. | ||
264 | |||
265 | inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not | ||
266 | enough memory. msg is set to null if there is no error message. | ||
267 | inflateInit does not perform any decompression: this will be done by | ||
268 | inflate(). | ||
269 | */ | ||
270 | |||
271 | |||
272 | extern int inflate OF((z_stream *strm, int flush)); | ||
273 | /* | ||
274 | Performs one or both of the following actions: | ||
275 | |||
276 | - Decompress more input starting at next_in and update next_in and avail_in | ||
277 | accordingly. If not all input can be processed (because there is not | ||
278 | enough room in the output buffer), next_in is updated and processing | ||
279 | will resume at this point for the next call of inflate(). | ||
280 | |||
281 | - Provide more output starting at next_out and update next_out and avail_out | ||
282 | accordingly. inflate() always provides as much output as possible | ||
283 | (until there is no more input data or no more space in the output buffer). | ||
284 | |||
285 | Before the call of inflate(), the application should ensure that at least | ||
286 | one of the actions is possible, by providing more input and/or consuming | ||
287 | more output, and updating the next_* and avail_* values accordingly. | ||
288 | The application can consume the uncompressed output when it wants, for | ||
289 | example when the output buffer is full (avail_out == 0), or after each | ||
290 | call of inflate(). | ||
291 | |||
292 | If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, | ||
293 | inflate flushes as much output as possible to the output buffer. The | ||
294 | flushing behavior of inflate is not specified for values of the flush | ||
295 | parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the | ||
296 | current implementation actually flushes as much output as possible | ||
297 | anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data | ||
298 | has been consumed, it is expecting to see the length field of a stored | ||
299 | block; if not, it returns Z_DATA_ERROR. | ||
300 | |||
301 | inflate() should normally be called until it returns Z_STREAM_END or an | ||
302 | error. However if all decompression is to be performed in a single step | ||
303 | (a single call of inflate), the parameter flush should be set to | ||
304 | Z_FINISH. In this case all pending input is processed and all pending | ||
305 | output is flushed; avail_out must be large enough to hold all the | ||
306 | uncompressed data. (The size of the uncompressed data may have been saved | ||
307 | by the compressor for this purpose.) The next operation on this stream must | ||
308 | be inflateEnd to deallocate the decompression state. The use of Z_FINISH | ||
309 | is never required, but can be used to inform inflate that a faster routine | ||
310 | may be used for the single inflate() call. | ||
311 | |||
312 | inflate() returns Z_OK if some progress has been made (more input | ||
313 | processed or more output produced), Z_STREAM_END if the end of the | ||
314 | compressed data has been reached and all uncompressed output has been | ||
315 | produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if | ||
316 | the stream structure was inconsistent (for example if next_in or next_out | ||
317 | was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no | ||
318 | progress is possible or if there was not enough room in the output buffer | ||
319 | when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then | ||
320 | call inflateSync to look for a good compression block. */ | ||
321 | |||
322 | |||
323 | extern int inflateEnd OF((z_stream *strm)); | ||
324 | /* | ||
325 | All dynamically allocated data structures for this stream are freed. | ||
326 | This function discards any unprocessed input and does not flush any | ||
327 | pending output. | ||
328 | |||
329 | inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state | ||
330 | was inconsistent. In the error case, msg may be set but then points to a | ||
331 | static string (which must not be deallocated). | ||
332 | */ | ||
333 | |||
334 | /* advanced functions */ | ||
335 | |||
336 | extern int inflateInit2 OF((z_stream *strm, | ||
337 | int windowBits)); | ||
338 | /* | ||
339 | This is another version of inflateInit with more compression options. The | ||
340 | fields next_out, zalloc and zfree must be initialized before by the caller. | ||
341 | |||
342 | The windowBits parameter is the base two logarithm of the maximum window | ||
343 | size (the size of the history buffer). It should be in the range 8..15 for | ||
344 | this version of the library (the value 16 will be allowed soon). The | ||
345 | default value is 15 if inflateInit is used instead. If a compressed stream | ||
346 | with a larger window size is given as input, inflate() will return with | ||
347 | the error code Z_DATA_ERROR instead of trying to allocate a larger window. | ||
348 | |||
349 | If next_out is not null, the library will use this buffer for the history | ||
350 | buffer; the buffer must either be large enough to hold the entire output | ||
351 | data, or have at least 1<<windowBits bytes. If next_out is null, the | ||
352 | library will allocate its own buffer (and leave next_out null). next_in | ||
353 | need not be provided here but must be provided by the application for the | ||
354 | next call of inflate(). | ||
355 | |||
356 | If the history buffer is provided by the application, next_out must | ||
357 | never be changed by the application since the decompressor maintains | ||
358 | history information inside this buffer from call to call; the application | ||
359 | can only reset next_out to the beginning of the history buffer when | ||
360 | avail_out is zero and all output has been consumed. | ||
361 | |||
362 | inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was | ||
363 | not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as | ||
364 | windowBits < 8). msg is set to null if there is no error message. | ||
365 | inflateInit2 does not perform any decompression: this will be done by | ||
366 | inflate(). | ||
367 | */ | ||
368 | |||
369 | extern int inflateSync OF((z_stream *strm)); | ||
370 | /* | ||
371 | Skips invalid compressed data until the special marker (see deflate() | ||
372 | above) can be found, or until all available input is skipped. No output | ||
373 | is provided. | ||
374 | |||
375 | inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR | ||
376 | if no more input was provided, Z_DATA_ERROR if no marker has been found, | ||
377 | or Z_STREAM_ERROR if the stream structure was inconsistent. In the success | ||
378 | case, the application may save the current current value of total_in which | ||
379 | indicates where valid compressed data was found. In the error case, the | ||
380 | application may repeatedly call inflateSync, providing more input each time, | ||
381 | until success or end of the input data. | ||
382 | */ | ||
383 | |||
384 | extern int inflateReset OF((z_stream *strm)); | ||
385 | /* | ||
386 | This function is equivalent to inflateEnd followed by inflateInit, | ||
387 | but does not free and reallocate all the internal decompression state. | ||
388 | The stream will keep attributes that may have been set by inflateInit2. | ||
389 | |||
390 | inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source | ||
391 | stream state was inconsistent (such as zalloc or state being NULL). | ||
392 | */ | ||
393 | |||
394 | extern int inflateIncomp OF((z_stream *strm)); | ||
395 | /* | ||
396 | This function adds the data at next_in (avail_in bytes) to the output | ||
397 | history without performing any output. There must be no pending output, | ||
398 | and the decompressor must be expecting to see the start of a block. | ||
399 | Calling this function is equivalent to decompressing a stored block | ||
400 | containing the data at next_in (except that the data is not output). | ||
401 | */ | ||
402 | |||
403 | /* checksum functions */ | ||
404 | |||
405 | /* | ||
406 | This function is not related to compression but is exported | ||
407 | anyway because it might be useful in applications using the | ||
408 | compression library. | ||
409 | */ | ||
410 | |||
411 | extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len)); | ||
412 | |||
413 | /* | ||
414 | Update a running Adler-32 checksum with the bytes buf[0..len-1] and | ||
415 | return the updated checksum. If buf is NULL, this function returns | ||
416 | the required initial value for the checksum. | ||
417 | An Adler-32 checksum is almost as reliable as a CRC32 but can be computed | ||
418 | much faster. Usage example: | ||
419 | |||
420 | uLong adler = adler32(0L, Z_NULL, 0); | ||
421 | |||
422 | while (read_buffer(buffer, length) != EOF) { | ||
423 | adler = adler32(adler, buffer, length); | ||
424 | } | ||
425 | if (adler != original_adler) error(); | ||
426 | */ | ||
427 | |||
428 | #ifndef _Z_UTIL_H | ||
429 | struct internal_state {int dummy;}; /* hack for buggy compilers */ | ||
430 | #endif | ||
431 | |||
432 | #endif /* _ZLIB_H */ | ||