mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
![Nick Desaulniers](/assets/img/avatar_default.png)
The kernel uses `-include` to include include/linux/compiler_types.h
into all translation units (see scripts/Makefile.lib), which #includes
compiler_attributes.h.
arch/powerpc/boot/ uses different compiler flags from the rest of the
kernel. As such, it doesn't contain the definitions from these headers,
and redefines a few that it needs.
For the purpose of enabling -Wimplicit-fallthrough for ppc, include
compiler_attributes.h via `-include`.
It was also noted in 6a9dc5fd61
that we could -D__KERNEL__ and
-include compiler_types.h like the main kernel does, though testing that
produces a whole sea of warnings to cleanup. This approach is minimally
invasive. And it also helps to entice a cleanup.
Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
Tested-by: Nathan Chancellor <natechancellor@gmail.com>
Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
Acked-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Acked-by: Miguel Ojeda <ojeda@kernel.org>
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://github.com/ClangBuiltLinux/linux/issues/236
[ Gustavo: Massage a bit as per Miguel's suggestion. ]
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
143 lines
3.6 KiB
C
143 lines
3.6 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Wrapper around the kernel's pre-boot decompression library.
|
|
*
|
|
* Copyright (C) IBM Corporation 2016.
|
|
*/
|
|
|
|
#include "elf.h"
|
|
#include "page.h"
|
|
#include "string.h"
|
|
#include "stdio.h"
|
|
#include "ops.h"
|
|
#include "reg.h"
|
|
#include "types.h"
|
|
|
|
/*
|
|
* The decompressor_*.c files play #ifdef games so they can be used in both
|
|
* pre-boot and regular kernel code. We need these definitions to make the
|
|
* includes work.
|
|
*/
|
|
|
|
#define STATIC static
|
|
#define INIT
|
|
|
|
/*
|
|
* The build process will copy the required zlib source files and headers
|
|
* out of lib/ and "fix" the includes so they do not pull in other kernel
|
|
* headers.
|
|
*/
|
|
|
|
#ifdef CONFIG_KERNEL_GZIP
|
|
# include "decompress_inflate.c"
|
|
#endif
|
|
|
|
#ifdef CONFIG_KERNEL_XZ
|
|
# include "xz_config.h"
|
|
# include "../../../lib/decompress_unxz.c"
|
|
#endif
|
|
|
|
/* globals for tracking the state of the decompression */
|
|
static unsigned long decompressed_bytes;
|
|
static unsigned long limit;
|
|
static unsigned long skip;
|
|
static char *output_buffer;
|
|
|
|
/*
|
|
* flush() is called by __decompress() when the decompressor's scratch buffer is
|
|
* full.
|
|
*/
|
|
static long flush(void *v, unsigned long buffer_size)
|
|
{
|
|
unsigned long end = decompressed_bytes + buffer_size;
|
|
unsigned long size = buffer_size;
|
|
unsigned long offset = 0;
|
|
char *in = v;
|
|
char *out;
|
|
|
|
/*
|
|
* if we hit our decompression limit, we need to fake an error to abort
|
|
* the in-progress decompression.
|
|
*/
|
|
if (decompressed_bytes >= limit)
|
|
return -1;
|
|
|
|
/* skip this entire block */
|
|
if (end <= skip) {
|
|
decompressed_bytes += buffer_size;
|
|
return buffer_size;
|
|
}
|
|
|
|
/* skip some data at the start, but keep the rest of the block */
|
|
if (decompressed_bytes < skip && end > skip) {
|
|
offset = skip - decompressed_bytes;
|
|
|
|
in += offset;
|
|
size -= offset;
|
|
decompressed_bytes += offset;
|
|
}
|
|
|
|
out = &output_buffer[decompressed_bytes - skip];
|
|
size = min(decompressed_bytes + size, limit) - decompressed_bytes;
|
|
|
|
memcpy(out, in, size);
|
|
decompressed_bytes += size;
|
|
|
|
return buffer_size;
|
|
}
|
|
|
|
static void print_err(char *s)
|
|
{
|
|
/* suppress the "error" when we terminate the decompressor */
|
|
if (decompressed_bytes >= limit)
|
|
return;
|
|
|
|
printf("Decompression error: '%s'\n\r", s);
|
|
}
|
|
|
|
/**
|
|
* partial_decompress - decompresses part or all of a compressed buffer
|
|
* @inbuf: input buffer
|
|
* @input_size: length of the input buffer
|
|
* @outbuf: input buffer
|
|
* @output_size: length of the input buffer
|
|
* @skip number of output bytes to ignore
|
|
*
|
|
* This function takes compressed data from inbuf, decompresses and write it to
|
|
* outbuf. Once output_size bytes are written to the output buffer, or the
|
|
* stream is exhausted the function will return the number of bytes that were
|
|
* decompressed. Otherwise it will return whatever error code the decompressor
|
|
* reported (NB: This is specific to each decompressor type).
|
|
*
|
|
* The skip functionality is mainly there so the program and discover
|
|
* the size of the compressed image so that it can ask firmware (if present)
|
|
* for an appropriately sized buffer.
|
|
*/
|
|
long partial_decompress(void *inbuf, unsigned long input_size,
|
|
void *outbuf, unsigned long output_size, unsigned long _skip)
|
|
{
|
|
int ret;
|
|
|
|
/*
|
|
* The skipped bytes needs to be included in the size of data we want
|
|
* to decompress.
|
|
*/
|
|
output_size += _skip;
|
|
|
|
decompressed_bytes = 0;
|
|
output_buffer = outbuf;
|
|
limit = output_size;
|
|
skip = _skip;
|
|
|
|
ret = __decompress(inbuf, input_size, NULL, flush, outbuf,
|
|
output_size, NULL, print_err);
|
|
|
|
/*
|
|
* If decompression was aborted due to an actual error rather than
|
|
* a fake error that we used to abort, then we should report it.
|
|
*/
|
|
if (decompressed_bytes < limit)
|
|
return ret;
|
|
|
|
return decompressed_bytes - skip;
|
|
}
|