Messages in this thread | | | From | Nick Desaulniers <> | Date | Fri, 26 Jun 2020 14:36:44 -0700 | Subject | Re: [PATCH v2 1/2] arm/build: Warn on orphan section placement |
| |
On Tue, Jun 23, 2020 at 5:03 PM Nick Desaulniers <ndesaulniers@google.com> wrote: > > On Mon, Jun 22, 2020 at 1:49 PM Kees Cook <keescook@chromium.org> wrote: > > > > --- a/arch/arm/kernel/vmlinux.lds.h > > +++ b/arch/arm/include/asm/vmlinux.lds.h > > @@ -1,4 +1,5 @@ > > /* SPDX-License-Identifier: GPL-2.0 */ > > +#include <asm-generic/vmlinux.lds.h> > > > > #ifdef CONFIG_HOTPLUG_CPU > > #define ARM_CPU_DISCARD(x) > > @@ -37,6 +38,13 @@ > > *(.idmap.text) \ > > __idmap_text_end = .; \ > > > > +#define ARM_COMMON_DISCARD \ > > + *(.ARM.attributes) \ > > I could have sworn that someone (Eli?) once told me that this section > (.ARM.attributes) is used for disambiguating which ARM version or > which optional extensions were used when compiling, and that without > this section, one would not be able to disassemble 32b ARM precisely. > If that's the case, we might not want to discard it?
Yep, looks like ELFObjectFileBase::getARMFeatures() in llvm/lib/Object/ELFObjectFile.cpp does exactly that and more. https://github.com/llvm/llvm-project/blob/8808574e7438c8768b78ae7dd0f029385c6df01d/llvm/lib/Object/ELFObjectFile.cpp#L359-L441 https://github.com/llvm/llvm-project/blob/8808574e7438c8768b78ae7dd0f029385c6df01d/llvm/lib/Object/ELFObjectFile.cpp#L159-L287
As a test, let's do: $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make LLVM=1 -j71 defconfig (so armv7) $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make LLVM=1 -j71 (then pick any random object file) $ llvm-readelf -S arch/arm/kernel/bugs.o | grep attri [15] .ARM.attributes ARM_ATTRIBUTES 00000000 0000f7 000037 00 0 0 1 $ llvm-readelf --arch-specific arch/arm/kernel/bugs.o | grep -A 2 CPU_arch TagName: CPU_arch Description: ARM v7 } And let's see if this actually has a difference on the disassembly. $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make LLVM=1 -j71 (full build, since we're talking about linker script changes for vmlinux) $ llvm-objdump -d vmlinux > prepatch.txt (apply your patch) $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make LLVM=1 -j71 clean $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make LLVM=1 -j71 $ llvm-objdump -d vmlinux > postpatch.txt $ diff -u prepatch.txt postpatch.txt | less
No difference. Eh. Checking again with arm-linux-gnueabihf-objdump, it seems some constants are slightly different for `movw`'s though. Not sure what's that about.
If I enable CONFIG_THUMB2_KERNEL=y, is where things become interesting. llvm-objdump produces wildly different disassembly before vs after removing .ARM.attributes. There's also lots of decode errors in the disassembly.
Repeating the thumb2 test with GNU objdump, I only see slight differences in constants values for operands to `movw`. So it looks like GNU objdump doesn't rely on .ARM.attributes to disambiguate between ARM vs THUMB2 instructions like llvm-objdump does. We can probably improve llvm-objdump, but I'd rather not discard this section for now.
(also, I didn't test armv6, v5, etc, but those might be interesting tests, too, should we want to discard this section. Also, I think we can explicitly specify --triple=thumbv7-linux-gnueabihf to llvm-objdump, but I'd prefer it if my disassembler did the work for me, since I'm lazy)
(oh man, the bytes are printed with different endianness between arm-linux-gnueabihf-objdump and llvm-objdump...guessing that's a bug in llvm).
-- Thanks, ~Nick Desaulniers
| |