Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign up.note.rustc dylib section flagged SHF_ALLOC on Linux (can cause crashes) #26764
Comments
sfackler
added
O-linux
T-compiler
labels
Jul 3, 2015
This comment has been minimized.
This comment has been minimized.
|
You could use module-level inline asm; not sure if that qualifies as "elegant". |
saschmit
referenced this issue
Jul 29, 2015
Closed
readelf complains that .note.rustc is malformed #27372
This comment has been minimized.
This comment has been minimized.
benpye
commented
May 5, 2016
|
Just to add, this is currently affecting WSL too, after applying the patch given (updated for current master), rust seems to run fine there. I equally can't find any way of specifying not to apply the SHF_ALLOC flag to the section with the LLVM API... |
This comment has been minimized.
This comment has been minimized.
|
To expand on that: LLVM internally removes |
This comment has been minimized.
This comment has been minimized.
|
My testcase so far: #![crate_type="dylib"]
// Any large (>8MB AFAICT) file works, librustc_llvm happens to take up 44MB.
pub const BLOB: &'static [u8] =
include_bytes!("build/x86_64-unknown-linux-gnu/stage0/lib/librustc_llvm-a4922355.so");Running |
This comment has been minimized.
This comment has been minimized.
|
FYI, I filed a glibc bug about the improper |
tylerwhall commentedJul 3, 2015
Having the metadata note section flagged "alloc" can cause two types of crashes in certain environments.
1. Dynamic loader crash
Glibc's dynamic loader will try to allocate and copy the entire section onto the stack which will crash if the stack size is limited. This section is particularly large (~2MB for libstd) - not something that can generally be expected to fit on the stack.
The loader is searching for .note.ABI-tag, but does so by reading in any PT_NOTE headers. Because the metadata section is flagged alloc, it gets an entry in the program header, causing it to get loaded by this code.
http://osxr.org/glibc/source/elf/dl-load.c?!v=glibc-2.19#1869 (Note the alloca() at 1879)
I think this may be the cause of #22528, or other crashes with open_verify() in the call stack.
A workaround of using objcopy -R to remove the section fixes this problem, but leaves the object in a brittle state, described below.
2. Crashes in stripped and prelinked shared objects
Working around 1. by stripping out .note.rustc causes a problem with section numbering. Pulling the section out from before another ALLOC section (.bss in the example below) causes that section to be renumbered. Neither GNU strip nor objcopy fix the rest of the references in the executable that point to the section by its index. In particular, entries in the .dynamic section now point to the next section (.comment, here) which breaks when prelinking.
Prelink decides not to fix up the symbols in the dynamic section because it thinks they point to .comment, a section that didn't get relocated during prelinking. So BSS gets relocated, but the dynamic symbols point to the non-prelinked address, causing the program to segfault when it tries to access exported symbols in BSS.
readelf -S libstd-4e7c5e5c.so (current behavior)
To fix this, I'm currently using this patch as a workaround.
tylerwhall@fc91059
It runs objcopy on the intermediate metadata object to remove the alloc and write flags. This causes the final link to place the metadata section at the end of the executable and not generate a program header entry.
The fixed version has the metadata with no flags set, no load address, and located near the end of the file along with the debug sections where it can be safely stripped.
readelf -S libstd-4e7c5e5c.so (desired behavior)
Obviously running objcopy like this is not portable. Calling llvm::LLVMSetGlobalConstant() on the metadata variable is enough to remove the SHF_WRITE flag, but I couldn't find a way with LLVM's API to output a section that didn't request to be loaded at run time. Hopefully someone who knows more about LLVM can come up with a more elegant solution to remove SHF_ALLOC from the intermediate metadata object.