Description
The link_section
attribute doesn't get applied to global const
values.
Consider the following program (which uses static
instead of const
, and correctly applies the link_section
to HELLO
):
#[link_section = ".data,__yes_this_is_a_custom_link_section"]
static HELLO: [u8; 6] = *b"hello\0";
extern {
fn puts(_str: *const u8) -> i32;
}
fn main() {
unsafe { puts(&HELLO as *const u8) };
}
As can be seen in the LLVM IR (Playground link), HELLO
is correctly given the custom section assignment:
@_ZN10playground5HELLO17h62136d8dd807037cE = internal constant [6 x i8] c"hello\00", section ".data,__yes_this_is_a_custom_link_section", align 1
; playground::main
; Function Attrs: nounwind uwtable
define internal void @_ZN10playground4main17h4b9f3b1aa6035d1eE() unnamed_addr #0 {
start:
%0 = tail call i32 @puts(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @_ZN10playground5HELLO17h62136d8dd807037cE, i64 0, i64 0))
ret void
}
But if we change HELLO
to be a const
instead of static
:
#[link_section = ".data,__yes_this_is_a_custom_link_section"]
const HELLO: [u8; 6] = *b"hello\0";
extern {
fn puts(_str: *const u8) -> i32;
}
fn main() {
unsafe { puts(&HELLO as *const u8) };
}
Then the string no longer has the custom section applied (Playground link):
@byte_str.0 = private unnamed_addr constant [6 x i8] c"hello\00", align 8
; playground::main
; Function Attrs: nounwind uwtable
define internal void @_ZN10playground4main17h4b9f3b1aa6035d1eE() unnamed_addr #0 {
start:
%0 = tail call i32 @puts(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @byte_str.0, i64 0, i64 0))
ret void
}
I think that Rust should propagate the link section to all instances of the string. That is, @byte_str.0
(and any other duplicate instances of the const
) should be defined as @byte_str.0 = private unnamed_addr constant [6 x i8] c"hello\00", section ".data,__yes_this_is_a_custom_link_section", align 8
.
Meta info: I've tested this in both 1.22.1 and 1.24.0-nightly (2017-12-22 5165ee9). Both produce the same results.