Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Linker script macros to generate Image header fields.
0004  *
0005  * Copyright (C) 2014 ARM Ltd.
0006  */
0007 #ifndef __ARM64_KERNEL_IMAGE_H
0008 #define __ARM64_KERNEL_IMAGE_H
0009 
0010 #ifndef LINKER_SCRIPT
0011 #error This file should only be included in vmlinux.lds.S
0012 #endif
0013 
0014 #include <asm/image.h>
0015 
0016 /*
0017  * There aren't any ELF relocations we can use to endian-swap values known only
0018  * at link time (e.g. the subtraction of two symbol addresses), so we must get
0019  * the linker to endian-swap certain values before emitting them.
0020  *
0021  * Note that, in order for this to work when building the ELF64 PIE executable
0022  * (for KASLR), these values should not be referenced via R_AARCH64_ABS64
0023  * relocations, since these are fixed up at runtime rather than at build time
0024  * when PIE is in effect. So we need to split them up in 32-bit high and low
0025  * words.
0026  */
0027 #ifdef CONFIG_CPU_BIG_ENDIAN
0028 #define DATA_LE32(data)             \
0029     ((((data) & 0x000000ff) << 24) |    \
0030      (((data) & 0x0000ff00) << 8)  |    \
0031      (((data) & 0x00ff0000) >> 8)  |    \
0032      (((data) & 0xff000000) >> 24))
0033 #else
0034 #define DATA_LE32(data) ((data) & 0xffffffff)
0035 #endif
0036 
0037 #define DEFINE_IMAGE_LE64(sym, data)                \
0038     sym##_lo32 = DATA_LE32((data) & 0xffffffff);        \
0039     sym##_hi32 = DATA_LE32((data) >> 32)
0040 
0041 #define __HEAD_FLAG(field)  (__HEAD_FLAG_##field << \
0042                     ARM64_IMAGE_FLAG_##field##_SHIFT)
0043 
0044 #ifdef CONFIG_CPU_BIG_ENDIAN
0045 #define __HEAD_FLAG_BE      ARM64_IMAGE_FLAG_BE
0046 #else
0047 #define __HEAD_FLAG_BE      ARM64_IMAGE_FLAG_LE
0048 #endif
0049 
0050 #define __HEAD_FLAG_PAGE_SIZE   ((PAGE_SHIFT - 10) / 2)
0051 
0052 #define __HEAD_FLAG_PHYS_BASE   1
0053 
0054 #define __HEAD_FLAGS        (__HEAD_FLAG(BE)    | \
0055                  __HEAD_FLAG(PAGE_SIZE) | \
0056                  __HEAD_FLAG(PHYS_BASE))
0057 
0058 /*
0059  * These will output as part of the Image header, which should be little-endian
0060  * regardless of the endianness of the kernel. While constant values could be
0061  * endian swapped in head.S, all are done here for consistency.
0062  */
0063 #define HEAD_SYMBOLS                        \
0064     DEFINE_IMAGE_LE64(_kernel_size_le, _end - _text);   \
0065     DEFINE_IMAGE_LE64(_kernel_flags_le, __HEAD_FLAGS);
0066 
0067 #endif /* __ARM64_KERNEL_IMAGE_H */