about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-07-23 20:04:53 -0700
committerbors <bors@rust-lang.org>2013-07-23 20:04:53 -0700
commitaf78e23006d9795bca32267a31e6f3cb9e73a6e1 (patch)
treedf940605470509921b4f69f836a7519308a2662b /src
parent359755a39a1d216a03a4e4d0b14e64e6610bbf91 (diff)
parentc6c1472c6845ea02fad009603b1c2331b679ed67 (diff)
downloadrust-af78e23006d9795bca32267a31e6f3cb9e73a6e1.tar.gz
rust-af78e23006d9795bca32267a31e6f3cb9e73a6e1.zip
auto merge of #7958 : kemurphy/rust/link-section, r=alexcrichton
This allows for control over the section placement of static, static
mut, and fn items.  One caveat is that if a static and a static mut are
placed in the same section, the static is declared first, and the static
mut is assigned to, the generated program crashes.  For example:

#[link_section=".boot"]
static foo : uint = 0xdeadbeef;

#[link_section=".boot"]
static mut bar : uint = 0xcafebabe;

Declaring bar first would mark .bootdata as writable, preventing the
crash when bar is written to.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/trans/base.rs11
-rw-r--r--src/test/run-pass/link-section.rs34
2 files changed, 44 insertions, 1 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 699cfab429b..bf5c5ac334d 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -2449,7 +2449,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
         let val = match item {
           ast_map::node_item(i, pth) => {
             let my_path = vec::append((*pth).clone(), [path_name(i.ident)]);
-            match i.node {
+            let v = match i.node {
               ast::item_static(_, m, expr) => {
                 let typ = ty::node_id_to_type(ccx.tcx, i.id);
                 let s = mangle_exported_name(ccx, my_path, typ);
@@ -2481,7 +2481,16 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
                 llfn
               }
               _ => fail!("get_item_val: weird result in table")
+            };
+            match (attr::first_attr_value_str_by_name(i.attrs, "link_section")) {
+                Some(sect) => unsafe {
+                    do sect.as_c_str |buf| {
+                        llvm::LLVMSetSection(v, buf);
+                    }
+                },
+                None => ()
             }
+            v
           }
           ast_map::node_trait_method(trait_method, _, pth) => {
             debug!("get_item_val(): processing a node_trait_method");
diff --git a/src/test/run-pass/link-section.rs b/src/test/run-pass/link-section.rs
new file mode 100644
index 00000000000..ff1e4740394
--- /dev/null
+++ b/src/test/run-pass/link-section.rs
@@ -0,0 +1,34 @@
+#[cfg(not(target_os = "macos"))]
+#[link_section=".moretext"]
+fn i_live_in_more_text() -> &'static str {
+    "knock knock"
+}
+
+#[cfg(not(target_os = "macos"))]
+#[link_section=".imm"]
+static magic: uint = 42;
+
+#[cfg(not(target_os = "macos"))]
+#[link_section=".mut"]
+static mut frobulator: uint = 0xdeadbeef;
+
+#[cfg(target_os = "macos")]
+#[link_section="__TEXT,__moretext"]
+fn i_live_in_more_text() -> &'static str {
+    "knock knock"
+}
+
+#[cfg(target_os = "macos")]
+#[link_section="__RODATA,__imm"]
+static magic: uint = 42;
+
+#[cfg(target_os = "macos")]
+#[link_section="__DATA,__mut"]
+static mut frobulator: uint = 0xdeadbeef;
+
+fn main() {
+    unsafe {
+        frobulator = 0xcafebabe;
+        printfln!("%? %? %?", i_live_in_more_text(), magic, frobulator);
+    }
+}