1
Fork 0

Support ARM and Android

Conflicts:
	src/libcore/os.rs
	src/librustc/back/link.rs
	src/librustc/driver/driver.rs
	src/librustc/metadata/loader.rs
	src/librustc/middle/trans/base.rs
This commit is contained in:
kyeongwoon 2012-11-30 09:21:49 +09:00 committed by Brian Anderson
parent 27e6a0fa56
commit 987f824f23
35 changed files with 599 additions and 30 deletions

View file

@ -241,7 +241,7 @@ DRIVER_CRATE := $(S)src/driver/driver.rs
###################################################################### ######################################################################
# FIXME: x86-ism # FIXME: x86-ism
LLVM_COMPONENTS=x86 ipo bitreader bitwriter linker asmparser jit mcjit \ LLVM_COMPONENTS=x86 arm ipo bitreader bitwriter linker asmparser jit mcjit \
interpreter interpreter
define DEF_LLVM_VARS define DEF_LLVM_VARS

2
configure vendored
View file

@ -717,7 +717,7 @@ do
then then
msg "configuring LLVM for $t" msg "configuring LLVM for $t"
LLVM_TARGETS="--enable-targets=x86,x86_64" LLVM_TARGETS="--enable-targets=x86,x86_64,arm"
LLVM_BUILD="--build=$t" LLVM_BUILD="--build=$t"
LLVM_HOST="--host=$t" LLVM_HOST="--host=$t"
LLVM_TARGET="--target=$t" LLVM_TARGET="--target=$t"

View file

@ -40,11 +40,13 @@ struct AllocHeader { priv opaque: () }
struct MemoryRegion { priv opaque: () } struct MemoryRegion { priv opaque: () }
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
struct Registers { struct Registers {
data: [u32 * 16] data: [u32 * 16]
} }
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
struct Context { struct Context {
regs: Registers, regs: Registers,
next: *Context, next: *Context,
@ -70,6 +72,7 @@ struct BoxedRegion {
} }
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
struct Task { struct Task {
// Public fields // Public fields
refcount: intptr_t, // 0 refcount: intptr_t, // 0

View file

@ -198,12 +198,14 @@ pub mod types {
// Standard types that are scalar but vary by OS and arch. // Standard types that are scalar but vary by OS and arch.
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
pub mod os { pub mod os {
pub mod common { pub mod common {
pub mod posix01 {} pub mod posix01 {}
} }
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")]
pub mod arch { pub mod arch {
pub mod c95 { pub mod c95 {
pub type c_char = i8; pub type c_char = i8;
@ -797,6 +799,7 @@ pub mod consts {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
pub mod os { pub mod os {
pub mod c95 { pub mod c95 {
pub const EXIT_FAILURE : int = 1; pub const EXIT_FAILURE : int = 1;
@ -1264,6 +1267,7 @@ pub mod funcs {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
pub mod posix88 { pub mod posix88 {
@ -1283,6 +1287,7 @@ pub mod funcs {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
#[cfg(target_os = "android")]
unsafe fn fstat(fildes: c_int, buf: *mut stat) -> c_int; unsafe fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
@ -1294,6 +1299,7 @@ pub mod funcs {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
#[cfg(target_os = "android")]
unsafe fn stat(path: *c_char, buf: *mut stat) -> c_int; unsafe fn stat(path: *c_char, buf: *mut stat) -> c_int;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
@ -1382,6 +1388,7 @@ pub mod funcs {
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
pub mod posix01 { pub mod posix01 {
@ -1394,6 +1401,7 @@ pub mod funcs {
pub extern mod stat_ { pub extern mod stat_ {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
#[cfg(target_os = "android")]
unsafe fn lstat(path: *c_char, buf: *mut stat) -> c_int; unsafe fn lstat(path: *c_char, buf: *mut stat) -> c_int;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
@ -1410,6 +1418,7 @@ pub mod funcs {
unsafe fn fsync(fd: c_int) -> c_int; unsafe fn fsync(fd: c_int) -> c_int;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
unsafe fn fdatasync(fd: c_int) -> c_int; unsafe fn fdatasync(fd: c_int) -> c_int;
unsafe fn setenv(name: *c_char, val: *c_char, unsafe fn setenv(name: *c_char, val: *c_char,
@ -1442,6 +1451,7 @@ pub mod funcs {
#[cfg(target_os = "win32")] #[cfg(target_os = "win32")]
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
pub mod posix08 { pub mod posix08 {
@ -1473,6 +1483,7 @@ pub mod funcs {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "win32")] #[cfg(target_os = "win32")]
pub mod bsd44 { pub mod bsd44 {
} }
@ -1492,6 +1503,7 @@ pub mod funcs {
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
pub mod extra { pub mod extra {
} }

View file

@ -325,6 +325,7 @@ pub fn fsync_fd(fd: c_int, _level: io::fsync::Level) -> c_int {
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int { pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
unsafe { unsafe {
use libc::funcs::posix01::unistd::*; use libc::funcs::posix01::unistd::*;
@ -449,6 +450,7 @@ pub fn self_exe_path() -> Option<Path> {
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
fn load_self() -> Option<~str> { fn load_self() -> Option<~str> {
unsafe { unsafe {
use libc::funcs::posix01::unistd::readlink; use libc::funcs::posix01::unistd::readlink;
@ -876,6 +878,7 @@ pub fn real_args() -> ~[~str] {
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
pub fn real_args() -> ~[~str] { pub fn real_args() -> ~[~str] {
unsafe { unsafe {
@ -976,7 +979,6 @@ pub mod consts {
pub const FAMILY: &str = "windows"; pub const FAMILY: &str = "windows";
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
use os::consts::macos::*; use os::consts::macos::*;
@ -986,6 +988,9 @@ pub mod consts {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
use os::consts::linux::*; use os::consts::linux::*;
#[cfg(target_os = "android")]
use os::consts::android::*;
#[cfg(target_os = "win32")] #[cfg(target_os = "win32")]
use os::consts::win32::*; use os::consts::win32::*;
@ -1010,6 +1015,13 @@ pub mod consts {
pub const EXE_SUFFIX: &str = ""; pub const EXE_SUFFIX: &str = "";
} }
pub mod android {
pub const SYSNAME: &str = "android";
pub const DLL_PREFIX: &str = "lib";
pub const DLL_SUFFIX: &str = ".so";
pub const EXE_SUFFIX: &str = "";
}
pub mod win32 { pub mod win32 {
pub const SYSNAME: &str = "win32"; pub const SYSNAME: &str = "win32";
pub const DLL_PREFIX: &str = ""; pub const DLL_PREFIX: &str = "";

View file

@ -89,8 +89,10 @@ pub pure fn Path(s: &str) -> Path {
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
mod stat { mod stat {
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")]
pub mod arch { pub mod arch {
use libc; use libc;

View file

@ -405,6 +405,7 @@ pub fn waitpid(pid: pid_t) -> int {
#[cfg(unix)] #[cfg(unix)]
fn waitpid_os(pid: pid_t) -> int { fn waitpid_os(pid: pid_t) -> int {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
fn WIFEXITED(status: i32) -> bool { fn WIFEXITED(status: i32) -> bool {
(status & 0xffi32) == 0i32 (status & 0xffi32) == 0i32
} }
@ -416,6 +417,7 @@ pub fn waitpid(pid: pid_t) -> int {
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
fn WEXITSTATUS(status: i32) -> i32 { fn WEXITSTATUS(status: i32) -> i32 {
(status >> 8i32) & 0xffi32 (status >> 8i32) & 0xffi32
} }

85
src/librustc/back/arm.rs Normal file
View file

@ -0,0 +1,85 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use back::target_strs;
use driver::session;
use session::sess_os_to_meta_os;
use metadata::loader::meta_section_name;
fn get_target_strs(target_os: session::os) -> target_strs::t {
return {
module_asm: ~"",
meta_sect_name: meta_section_name(sess_os_to_meta_os(target_os)),
data_layout: match target_os {
session::os_macos => {
~"e-p:32:32:32" +
~"-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" +
~"-f32:32:32-f64:64:64" +
~"-v64:64:64-v128:64:128" +
~"-a0:0:64-n32"
}
session::os_win32 => {
~"e-p:32:32:32" +
~"-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" +
~"-f32:32:32-f64:64:64" +
~"-v64:64:64-v128:64:128" +
~"-a0:0:64-n32"
}
session::os_linux => {
~"e-p:32:32:32" +
~"-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" +
~"-f32:32:32-f64:64:64" +
~"-v64:64:64-v128:64:128" +
~"-a0:0:64-n32"
}
session::os_android => {
~"e-p:32:32:32" +
~"-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" +
~"-f32:32:32-f64:64:64" +
~"-v64:64:64-v128:64:128" +
~"-a0:0:64-n32"
}
session::os_freebsd => {
~"e-p:32:32:32" +
~"-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" +
~"-f32:32:32-f64:64:64" +
~"-v64:64:64-v128:64:128" +
~"-a0:0:64-n32"
}
},
target_triple: match target_os {
session::os_macos => ~"arm-apple-darwin",
session::os_win32 => ~"arm-pc-mingw32",
session::os_linux => ~"arm-unknown-linux",
session::os_android => ~"arm-unknown-android",
session::os_freebsd => ~"arm-unknown-freebsd"
},
cc_args: ~[~"-marm"]
};
}
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//

View file

@ -30,7 +30,7 @@ use core::cmp;
use core::hash; use core::hash;
use core::io::{Writer, WriterUtil}; use core::io::{Writer, WriterUtil};
use core::libc::{c_int, c_uint, c_char}; use core::libc::{c_int, c_uint, c_char};
use core::os::consts::{macos, freebsd, linux, win32}; use core::os::consts::{macos, freebsd, linux, android, win32};
use core::os; use core::os;
use core::ptr; use core::ptr;
use core::run; use core::run;
@ -43,7 +43,7 @@ use syntax::ast_map::{path, path_mod, path_name};
use syntax::attr; use syntax::attr;
use syntax::print::pprust; use syntax::print::pprust;
pub enum output_type { enum output_type {
output_type_none, output_type_none,
output_type_bitcode, output_type_bitcode,
output_type_assembly, output_type_assembly,
@ -712,6 +712,7 @@ fn output_dll_filename(os: session::os, lm: &link_meta) -> ~str {
session::os_win32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX), session::os_win32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX),
session::os_macos => (macos::DLL_PREFIX, macos::DLL_SUFFIX), session::os_macos => (macos::DLL_PREFIX, macos::DLL_SUFFIX),
session::os_linux => (linux::DLL_PREFIX, linux::DLL_SUFFIX), session::os_linux => (linux::DLL_PREFIX, linux::DLL_SUFFIX),
session::os_android => (android::DLL_PREFIX, android::DLL_SUFFIX),
session::os_freebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX), session::os_freebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX),
}; };
return str::from_slice(dll_prefix) + libname + return str::from_slice(dll_prefix) + libname +
@ -758,7 +759,10 @@ fn link_binary(sess: Session,
// For win32, there is no cc command, // For win32, there is no cc command,
// so we add a condition to make it use gcc. // so we add a condition to make it use gcc.
let cc_prog: ~str = let cc_prog: ~str =
if sess.targ_cfg.os == session::os_win32 { ~"gcc" } else { ~"cc" }; if sess.targ_cfg.os == session::os_android {
~"arm-linux-androideabi-g++"
} else if sess.targ_cfg.os == session::os_win32 { ~"gcc" }
else { ~"cc" };
// The invocations of cc share some flags across platforms // The invocations of cc share some flags across platforms
let mut cc_args = let mut cc_args =
@ -831,6 +835,11 @@ fn link_binary(sess: Session,
// have to be explicit about linking to it. See #2510 // have to be explicit about linking to it. See #2510
cc_args.push(~"-lm"); cc_args.push(~"-lm");
} }
else if sess.targ_cfg.os == session::os_android {
cc_args.push_all(~[~"-ldl", ~"-llog", ~"-lsupc++",
~"-lgnustl_shared"]);
cc_args.push(~"-lm");
}
if sess.targ_cfg.os == session::os_freebsd { if sess.targ_cfg.os == session::os_freebsd {
cc_args.push_all(~[~"-pthread", ~"-lrt", cc_args.push_all(~[~"-pthread", ~"-lrt",
@ -851,7 +860,9 @@ fn link_binary(sess: Session,
} }
// Stack growth requires statically linking a __morestack function // Stack growth requires statically linking a __morestack function
if sess.targ_cfg.os != session::os_android {
cc_args.push(~"-lmorestack"); cc_args.push(~"-lmorestack");
}
// FIXME (#2397): At some point we want to rpath our guesses as to where // FIXME (#2397): At some point we want to rpath our guesses as to where
// extern libraries might live, based on the addl_lib_search_paths // extern libraries might live, based on the addl_lib_search_paths

View file

@ -130,7 +130,8 @@ fn get_rpath_relative_to_output(os: session::os,
// Mac doesn't appear to support $ORIGIN // Mac doesn't appear to support $ORIGIN
let prefix = match os { let prefix = match os {
session::os_linux | session::os_freebsd => "$ORIGIN", session::os_android |session::os_linux | session::os_freebsd
=> "$ORIGIN",
session::os_macos => "@executable_path", session::os_macos => "@executable_path",
session::os_win32 => util::unreachable() session::os_win32 => util::unreachable()
}; };
@ -331,6 +332,7 @@ mod test {
#[test] #[test]
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "andorid")]
fn test_rpath_relative() { fn test_rpath_relative() {
let o = session::os_linux; let o = session::os_linux;
let res = get_rpath_relative_to_output(o, let res = get_rpath_relative_to_output(o,

View file

@ -35,6 +35,9 @@ fn get_target_strs(target_os: session::os) -> target_strs::t {
session::os_linux => { session::os_linux => {
~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32" ~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32"
} }
session::os_android => {
~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32"
}
session::os_freebsd => { session::os_freebsd => {
~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32" ~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32"
@ -45,6 +48,7 @@ fn get_target_strs(target_os: session::os) -> target_strs::t {
session::os_macos => ~"i686-apple-darwin", session::os_macos => ~"i686-apple-darwin",
session::os_win32 => ~"i686-pc-mingw32", session::os_win32 => ~"i686-pc-mingw32",
session::os_linux => ~"i686-unknown-linux-gnu", session::os_linux => ~"i686-unknown-linux-gnu",
session::os_android => ~"i686-unknown-android-gnu",
session::os_freebsd => ~"i686-unknown-freebsd" session::os_freebsd => ~"i686-unknown-freebsd"
}, },

View file

@ -39,6 +39,11 @@ fn get_target_strs(target_os: session::os) -> target_strs::t {
~"f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-"+ ~"f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-"+
~"s0:64:64-f80:128:128-n8:16:32:64-S128" ~"s0:64:64-f80:128:128-n8:16:32:64-S128"
} }
session::os_android => {
~"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"+
~"f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-"+
~"s0:64:64-f80:128:128-n8:16:32:64-S128"
}
session::os_freebsd => { session::os_freebsd => {
~"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"+ ~"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"+
@ -51,6 +56,7 @@ fn get_target_strs(target_os: session::os) -> target_strs::t {
session::os_macos => ~"x86_64-apple-darwin", session::os_macos => ~"x86_64-apple-darwin",
session::os_win32 => ~"x86_64-pc-mingw32", session::os_win32 => ~"x86_64-pc-mingw32",
session::os_linux => ~"x86_64-unknown-linux-gnu", session::os_linux => ~"x86_64-unknown-linux-gnu",
session::os_android => ~"x86_64-unknown-android-gnu",
session::os_freebsd => ~"x86_64-unknown-freebsd", session::os_freebsd => ~"x86_64-unknown-freebsd",
}, },

View file

@ -12,7 +12,7 @@
use core::prelude::*; use core::prelude::*;
use back::link; use back::link;
use back::{x86, x86_64}; use back::{arm, x86, x86_64};
use front; use front;
use lib::llvm::llvm; use lib::llvm::llvm;
use metadata::{creader, cstore, filesearch}; use metadata::{creader, cstore, filesearch};
@ -74,9 +74,18 @@ fn default_configuration(sess: Session, +argv0: ~str, input: input) ->
session::os_win32 => ~"msvcrt.dll", session::os_win32 => ~"msvcrt.dll",
session::os_macos => ~"libc.dylib", session::os_macos => ~"libc.dylib",
session::os_linux => ~"libc.so.6", session::os_linux => ~"libc.so.6",
session::os_android => ~"libc.so",
session::os_freebsd => ~"libc.so.7" session::os_freebsd => ~"libc.so.7"
// _ { "libc.so" } // _ { "libc.so" }
}; };
let tos = match sess.targ_cfg.os {
session::os_win32 => ~"win32",
session::os_macos => ~"macos",
session::os_linux => ~"linux",
session::os_android => ~"android",
session::os_freebsd => ~"freebsd"
// _ { "libc.so" }
};
let mk = attr::mk_name_value_item_str; let mk = attr::mk_name_value_item_str;
@ -88,7 +97,7 @@ fn default_configuration(sess: Session, +argv0: ~str, input: input) ->
return ~[ // Target bindings. return ~[ // Target bindings.
attr::mk_word_item(str::from_slice(os::FAMILY)), attr::mk_word_item(str::from_slice(os::FAMILY)),
mk(~"target_os", str::from_slice(os::SYSNAME)), mk(~"target_os", tos),
mk(~"target_family", str::from_slice(os::FAMILY)), mk(~"target_family", str::from_slice(os::FAMILY)),
mk(~"target_arch", arch), mk(~"target_arch", arch),
mk(~"target_word_size", wordsz), mk(~"target_word_size", wordsz),
@ -424,6 +433,8 @@ fn get_os(triple: ~str) -> Option<session::os> {
Some(session::os_macos) Some(session::os_macos)
} else if str::contains(triple, ~"linux") { } else if str::contains(triple, ~"linux") {
Some(session::os_linux) Some(session::os_linux)
} else if str::contains(triple, ~"android") {
Some(session::os_android)
} else if str::contains(triple, ~"freebsd") { } else if str::contains(triple, ~"freebsd") {
Some(session::os_freebsd) Some(session::os_freebsd)
} else { None } } else { None }
@ -463,7 +474,7 @@ fn build_target_config(sopts: @session::options,
let target_strs = match arch { let target_strs = match arch {
session::arch_x86 => x86::get_target_strs(os), session::arch_x86 => x86::get_target_strs(os),
session::arch_x86_64 => x86_64::get_target_strs(os), session::arch_x86_64 => x86_64::get_target_strs(os),
session::arch_arm => x86::get_target_strs(os) session::arch_arm => arm::get_target_strs(os)
}; };
let target_cfg: @session::config = let target_cfg: @session::config =
@{os: os, arch: arch, target_strs: target_strs, int_type: int_type, @{os: os, arch: arch, target_strs: target_strs, int_type: int_type,

View file

@ -29,7 +29,7 @@ use syntax::parse::parse_sess;
use syntax::{ast, codemap}; use syntax::{ast, codemap};
use syntax; use syntax;
enum os { os_win32, os_macos, os_linux, os_freebsd, } enum os { os_win32, os_macos, os_linux, os_android, os_freebsd, }
impl os : cmp::Eq { impl os : cmp::Eq {
pure fn eq(&self, other: &os) -> bool { pure fn eq(&self, other: &os) -> bool {
@ -326,6 +326,7 @@ fn sess_os_to_meta_os(os: os) -> metadata::loader::os {
match os { match os {
os_win32 => loader::os_win32, os_win32 => loader::os_win32,
os_linux => loader::os_linux, os_linux => loader::os_linux,
os_android => loader::os_android,
os_macos => loader::os_macos, os_macos => loader::os_macos,
os_freebsd => loader::os_freebsd os_freebsd => loader::os_freebsd
} }

View file

@ -28,7 +28,7 @@ use core::cast;
use core::flate; use core::flate;
use core::io::WriterUtil; use core::io::WriterUtil;
use core::io; use core::io;
use core::os::consts::{macos, freebsd, linux, win32}; use core::os::consts::{macos, freebsd, linux, android, win32};
use core::option; use core::option;
use core::ptr; use core::ptr;
use core::str; use core::str;
@ -36,7 +36,7 @@ use core::uint;
use core::vec; use core::vec;
export os; export os;
export os_macos, os_win32, os_linux, os_freebsd; export os_macos, os_win32, os_linux, os_freebsd, os_android;
export ctxt; export ctxt;
export load_library_crate; export load_library_crate;
export list_file_metadata; export list_file_metadata;
@ -49,6 +49,7 @@ enum os {
os_macos, os_macos,
os_win32, os_win32,
os_linux, os_linux,
os_android,
os_freebsd os_freebsd
} }
@ -86,6 +87,7 @@ fn libname(cx: ctxt) -> {prefix: ~str, suffix: ~str} {
os_win32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX), os_win32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX),
os_macos => (macos::DLL_PREFIX, macos::DLL_SUFFIX), os_macos => (macos::DLL_PREFIX, macos::DLL_SUFFIX),
os_linux => (linux::DLL_PREFIX, linux::DLL_SUFFIX), os_linux => (linux::DLL_PREFIX, linux::DLL_SUFFIX),
os_android => (android::DLL_PREFIX, android::DLL_SUFFIX),
os_freebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX), os_freebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX),
}; };
return { return {
@ -251,6 +253,7 @@ fn meta_section_name(os: os) -> ~str {
os_macos => ~"__DATA,__note.rustc", os_macos => ~"__DATA,__note.rustc",
os_win32 => ~".note.rustc", os_win32 => ~".note.rustc",
os_linux => ~".note.rustc", os_linux => ~".note.rustc",
os_android => ~".note.rustc",
os_freebsd => ~".note.rustc" os_freebsd => ~".note.rustc"
} }
} }

View file

@ -2152,7 +2152,9 @@ fn register_fn_fuller(ccx: @crate_ctxt,
let llfn: ValueRef = decl_fn(ccx.llmod, copy ps, cc, llfty); let llfn: ValueRef = decl_fn(ccx.llmod, copy ps, cc, llfty);
ccx.item_symbols.insert(node_id, ps); ccx.item_symbols.insert(node_id, ps);
let is_main = is_main_name(path) && !ccx.sess.building_library; let is_main = is_main_name(path) && (!ccx.sess.building_library ||
(ccx.sess.building_library &&
ccx.sess.targ_cfg.os == session::os_android));
if is_main { create_main_wrapper(ccx, sp, llfn); } if is_main { create_main_wrapper(ccx, sp, llfn); }
llfn llfn
} }
@ -2202,7 +2204,12 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef) {
#[cfg(unix)] #[cfg(unix)]
fn main_name() -> ~str { return ~"main"; } fn main_name() -> ~str { return ~"main"; }
let llfty = T_fn(~[ccx.int_type, ccx.int_type], ccx.int_type); let llfty = T_fn(~[ccx.int_type, ccx.int_type], ccx.int_type);
let llfn = decl_cdecl_fn(ccx.llmod, main_name(), llfty);
let llfn = if ccx.sess.building_library {
decl_cdecl_fn(ccx.llmod, ~"amain", llfty)
} else {
decl_cdecl_fn(ccx.llmod, main_name(), llfty)
};
let llbb = str::as_c_str(~"top", |buf| { let llbb = str::as_c_str(~"top", |buf| {
unsafe { unsafe {
llvm::LLVMAppendBasicBlock(llfn, buf) llvm::LLVMAppendBasicBlock(llfn, buf)
@ -2217,14 +2224,16 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef) {
val_ty(crate_map)], ccx.int_type); val_ty(crate_map)], ccx.int_type);
let start = decl_cdecl_fn(ccx.llmod, ~"rust_start", start_ty); let start = decl_cdecl_fn(ccx.llmod, ~"rust_start", start_ty);
let args = unsafe { let args = if ccx.sess.building_library unsafe {
~[ ~[rust_main,
rust_main, llvm::LLVMConstInt(T_i32(), 0u as c_ulonglong, False),
llvm::LLVMGetParam(llfn, 0 as c_uint), llvm::LLVMConstInt(T_i32(), 0u as c_ulonglong, False),
llvm::LLVMGetParam(llfn, 1 as c_uint), crate_map]
crate_map } else unsafe {
] ~[rust_main, llvm::LLVMGetParam(llfn, 0 as c_uint),
llvm::LLVMGetParam(llfn, 1 as c_uint), crate_map]
}; };
let result = unsafe { let result = unsafe {
llvm::LLVMBuildCall(bld, start, vec::raw::to_ptr(args), llvm::LLVMBuildCall(bld, start, vec::raw::to_ptr(args),
args.len() as c_uint, noname()) args.len() as c_uint, noname())

View file

@ -15,6 +15,7 @@ use core::prelude::*;
use back::{link, abi}; use back::{link, abi};
use driver::session::arch_x86_64; use driver::session::arch_x86_64;
use driver::session::arch_arm;
use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg}; use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg};
use lib::llvm::{Struct, Array, ModuleRef, CallConv, Attribute}; use lib::llvm::{Struct, Array, ModuleRef, CallConv, Attribute};
use lib::llvm::{StructRetAttribute, ByValAttribute}; use lib::llvm::{StructRetAttribute, ByValAttribute};
@ -494,6 +495,8 @@ fn c_stack_tys(ccx: @crate_ctxt,
let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty); let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty);
let x86_64 = if ccx.sess.targ_cfg.arch == arch_x86_64 { let x86_64 = if ccx.sess.targ_cfg.arch == arch_x86_64 {
option::Some(x86_64_tys(llargtys, llretty, ret_def)) option::Some(x86_64_tys(llargtys, llretty, ret_def))
} else if ccx.sess.targ_cfg.arch == arch_arm {
option::Some(x86_64_tys(llargtys, llretty, ret_def))
} else { } else {
option::None option::None
}; };
@ -1491,6 +1494,14 @@ fn register_foreign_fn(ccx: @crate_ctxt,
register_fn_fuller(ccx, sp, /*bad*/copy path, node_id, attrs, register_fn_fuller(ccx, sp, /*bad*/copy path, node_id, attrs,
t, lib::llvm::CCallConv, fnty) t, lib::llvm::CCallConv, fnty)
} }
} else if ccx.sess.targ_cfg.arch == arch_arm {
let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty);
let x86_64 = x86_64_tys(llargtys, llretty, ret_def);
do decl_x86_64_fn(x86_64) |fnty| {
register_fn_fuller(ccx, sp, /*bad*/copy path, node_id, attrs,
t, lib::llvm::CCallConv, fnty)
}
} else { } else {
let llfty = T_fn(llargtys, llretty); let llfty = T_fn(llargtys, llretty);
register_fn_fuller(ccx, sp, path, node_id, attrs, register_fn_fuller(ccx, sp, path, node_id, attrs,

View file

@ -162,6 +162,8 @@ mod back {
#[legacy_exports] #[legacy_exports]
mod upcall; mod upcall;
#[legacy_exports] #[legacy_exports]
mod arm;
#[legacy_exports]
mod x86; mod x86;
#[legacy_exports] #[legacy_exports]
mod x86_64; mod x86_64;

View file

@ -1291,6 +1291,7 @@ pub mod test {
#[cfg(target_os="win32")] #[cfg(target_os="win32")]
#[cfg(target_os="darwin")] #[cfg(target_os="darwin")]
#[cfg(target_os="linux")] #[cfg(target_os="linux")]
#[cfg(target_os="android")]
pub mod tcp_ipv4_server_and_client_test { pub mod tcp_ipv4_server_and_client_test {
#[cfg(target_arch="x86_64")] #[cfg(target_arch="x86_64")]
pub mod impl64 { pub mod impl64 {
@ -1329,6 +1330,7 @@ pub mod test {
} }
} }
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
pub mod impl32 { pub mod impl32 {
use net::tcp::test::*; use net::tcp::test::*;

View file

@ -109,6 +109,7 @@ pub type uv_tcp_t_32bit_unix_riders = {
a29: *u8 a29: *u8
}; };
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
pub type uv_tcp_t_32bit_unix_riders = { pub type uv_tcp_t_32bit_unix_riders = {
a29: *u8, a30: *u8, a31: *u8, a29: *u8, a30: *u8, a31: *u8,
a32: *u8, a33: *u8, a34: *u8, a32: *u8, a33: *u8, a34: *u8,
@ -165,6 +166,7 @@ pub type uv_write_t_32bit_unix_riders = {
a13: *u8 a13: *u8
}; };
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
pub type uv_write_t_32bit_unix_riders = { pub type uv_write_t_32bit_unix_riders = {
a13: *u8, a14: *u8 a13: *u8, a14: *u8
}; };
@ -192,6 +194,7 @@ pub type uv_async_t_32bit_unix_riders = {
a10: *u8 a10: *u8
}; };
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
pub type uv_async_t_32bit_unix_riders = { pub type uv_async_t_32bit_unix_riders = {
a10: *u8, a11: *u8, a12: *u8, a13: *u8 a10: *u8, a11: *u8, a12: *u8, a13: *u8
}; };
@ -220,6 +223,7 @@ pub type uv_timer_t_32bit_unix_riders = {
a10: *u8, a11: *u8 a10: *u8, a11: *u8
}; };
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
pub type uv_timer_t_32bit_unix_riders = { pub type uv_timer_t_32bit_unix_riders = {
a10: *u8, a11: *u8, a12: *u8, a13: *u8, a10: *u8, a11: *u8, a12: *u8, a13: *u8,
a14: *u8, a15: *u8, a16: *u8 a14: *u8, a15: *u8, a16: *u8
@ -249,6 +253,7 @@ pub type sockaddr_in6 = {
a2: *u8, a3: *u8 a2: *u8, a3: *u8
}; };
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
pub type sockaddr_in6 = { pub type sockaddr_in6 = {
a0: *u8, a1: *u8, a0: *u8, a1: *u8,
a2: *u8, a3: *u8, a2: *u8, a3: *u8,
@ -267,6 +272,7 @@ pub mod addr_in_impl {
a2: *u8, a3: *u8 a2: *u8, a3: *u8
}; };
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
pub type addr_in = { pub type addr_in = {
a0: *u8, a1: *u8, a0: *u8, a1: *u8,
a2: *u8, a3: *u8, a2: *u8, a3: *u8,
@ -285,6 +291,7 @@ pub mod addr_in_impl {
// unix size: 48, 32bit: 32 // unix size: 48, 32bit: 32
pub type addrinfo = addrinfo_impl::addrinfo; pub type addrinfo = addrinfo_impl::addrinfo;
#[cfg(target_os="linux")] #[cfg(target_os="linux")]
#[cfg(target_os="android")]
pub mod addrinfo_impl { pub mod addrinfo_impl {
#[cfg(target_arch="x86_64")] #[cfg(target_arch="x86_64")]
pub type addrinfo = { pub type addrinfo = {
@ -292,6 +299,7 @@ pub mod addrinfo_impl {
a04: *u8, a05: *u8 a04: *u8, a05: *u8
}; };
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
pub type addrinfo = { pub type addrinfo = {
a00: *u8, a01: *u8, a02: *u8, a03: *u8, a00: *u8, a01: *u8, a02: *u8, a03: *u8,
a04: *u8, a05: *u8, a06: *u8, a07: *u8 a04: *u8, a05: *u8, a06: *u8, a07: *u8
@ -328,6 +336,7 @@ pub mod uv_ll_struct_stubgen {
pub fn gen_stub_uv_tcp_t() -> uv_tcp_t { pub fn gen_stub_uv_tcp_t() -> uv_tcp_t {
return gen_stub_os(); return gen_stub_os();
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[cfg(target_os = "android")]
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
pub fn gen_stub_os() -> uv_tcp_t { pub fn gen_stub_os() -> uv_tcp_t {
@ -358,6 +367,7 @@ pub mod uv_ll_struct_stubgen {
}; };
} }
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
pub fn gen_stub_arch() -> uv_tcp_t { pub fn gen_stub_arch() -> uv_tcp_t {
return { fields: { loop_handle: ptr::null(), type_: 0u32, return { fields: { loop_handle: ptr::null(), type_: 0u32,
close_cb: ptr::null(), close_cb: ptr::null(),
@ -443,6 +453,7 @@ pub mod uv_ll_struct_stubgen {
}; };
} }
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
#[cfg(target_arch="arm")]
pub fn gen_stub_arch() -> uv_async_t { pub fn gen_stub_arch() -> uv_async_t {
return { fields: { loop_handle: ptr::null(), type_: 0u32, return { fields: { loop_handle: ptr::null(), type_: 0u32,
close_cb: ptr::null(), close_cb: ptr::null(),
@ -492,6 +503,7 @@ pub mod uv_ll_struct_stubgen {
}; };
} }
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
#[cfg(target_arch="arm")]
pub fn gen_stub_arch() -> uv_timer_t { pub fn gen_stub_arch() -> uv_timer_t {
return { fields: { loop_handle: ptr::null(), type_: 0u32, return { fields: { loop_handle: ptr::null(), type_: 0u32,
close_cb: ptr::null(), close_cb: ptr::null(),
@ -541,6 +553,7 @@ pub mod uv_ll_struct_stubgen {
}; };
} }
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
pub fn gen_stub_arch() -> uv_write_t { pub fn gen_stub_arch() -> uv_write_t {
return { fields: { loop_handle: ptr::null(), type_: 0u32, return { fields: { loop_handle: ptr::null(), type_: 0u32,
close_cb: ptr::null(), close_cb: ptr::null(),
@ -1571,6 +1584,7 @@ pub mod test {
#[cfg(target_os="win32")] #[cfg(target_os="win32")]
#[cfg(target_os="darwin")] #[cfg(target_os="darwin")]
#[cfg(target_os="linux")] #[cfg(target_os="linux")]
#[cfg(target_os="android")]
pub mod tcp_and_server_client_test { pub mod tcp_and_server_client_test {
#[cfg(target_arch="x86_64")] #[cfg(target_arch="x86_64")]
pub mod impl64 { pub mod impl64 {
@ -1581,6 +1595,7 @@ pub mod test {
} }
} }
#[cfg(target_arch="x86")] #[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
pub mod impl32 { pub mod impl32 {
use uv_ll::test::*; use uv_ll::test::*;
#[test] #[test]

View file

@ -0,0 +1,47 @@
.text
.code 32
.arm
.align
.globl swap_registers
swap_registers:
str r0, [r0, #0]
str r3, [r0, #12]
str r4, [r0, #16]
str r5, [r0, #20]
str r6, [r0, #24]
str r7, [r0, #28]
str r8, [r0, #32]
str r9, [r0, #36]
str r10, [r0, #40]
str r11, [r0, #44]
str r12, [r0, #48]
str sp, [r0, #52]
str lr, [r0, #56]
mrs r2, cpsr
str r2, [r0, #64]
ldr r0, [r1, #0]
ldr r3, [r1, #12]
ldr r4, [r1, #16]
ldr r5, [r1, #20]
ldr r6, [r1, #24]
ldr r7, [r1, #28]
ldr r8, [r1, #32]
ldr r9, [r1, #36]
ldr r10, [r1, #40]
ldr r11, [r1, #44]
ldr r12, [r1, #48]
ldr sp, [r1, #52]
ldr lr, [r1, #56]
ldr r2, [r1, #64]
msr cpsr_cxsf, r2
mov pc, lr

27
src/rt/arch/arm/ccall.S Normal file
View file

@ -0,0 +1,27 @@
.text
.code 32
.arm
.align
.globl __morestack
.hidden __morestack
__morestack:
mov r3, sp
mov sp, r2
str r3, [sp]
str lr, [sp, #-4]
sub sp, #8
blx r1
add sp, #8
ldr lr, [sp, #-4]
ldr r3, [sp]
mov sp, r3
mov pc, lr

View file

@ -0,0 +1,36 @@
#include "context.h"
#include "../../rust_globals.h"
extern "C" void CDECL swap_registers(registers_t *oregs,
registers_t *regs)
asm ("swap_registers");
context::context()
{
assert((void*)&regs == (void*)this);
memset(&regs, 0, sizeof(regs));
}
void context::swap(context &out)
{
swap_registers(&out.regs, &regs);
}
void context::call(void *f, void *arg, void *stack)
{
// Get the current context, which we will then modify to call the
// given function.
swap(*this);
// set up the stack
uint32_t *sp = ( uint32_t *)stack;
//sp = align_down(sp);
// The final return address. 0 indicates the bottom of the stack
*--sp = 0;
regs.data[0] = ( uint32_t )arg; // r0
regs.data[13] = ( uint32_t )sp; //#52 sp, r13
regs.data[14] = ( uint32_t )f; //#60 pc, r15 --> lr,
// Last base pointer on the stack should be 0
}

43
src/rt/arch/arm/context.h Normal file
View file

@ -0,0 +1,43 @@
// -*- mode: c++ -*-
#ifndef CONTEXT_H
#define CONTEXT_H
#include <cstdlib>
#include <inttypes.h>
#include <stdint.h>
//#include <xmmintrin.h>
#include "vg/memcheck.h"
template<typename T>
T align_down(T sp)
{
// There is no platform we care about that needs more than a
// 16-byte alignment.
return (T)((uint32_t)sp & ~(16 - 1));
}
// The struct in which we store the saved data. This is mostly the
// volatile registers and instruction pointer, but it also includes
// RCX/RDI which are used to pass arguments. The indices for each
// register are found in "regs.h". Note that the alignment must be
// 16 bytes so that SSE instructions can be used.
#include "regs.h"
struct registers_t {
uint32_t data[RUSTRT_MAX];
} __attribute__((aligned(16)));
class context {
public:
registers_t regs;
context();
context *next;
void swap(context &out);
void call(void *f, void *arg, void *sp);
};
#endif

15
src/rt/arch/arm/gpr.cpp Normal file
View file

@ -0,0 +1,15 @@
#include "gpr.h"
#define LOAD(rn) do { \
uintptr_t tmp; \
asm("mov %%" #rn ",%0" : "=r" (tmp) :); \
this->rn = tmp; \
} while (0)
void rust_gpr::load() {
LOAD(r0); LOAD(r1); LOAD(r2); LOAD(r3);
LOAD(r4); LOAD(r5); LOAD(r6); LOAD(r7);
LOAD(r8); LOAD(r9); LOAD(r10); LOAD(r11);
LOAD(r12); LOAD(r13); LOAD(r14); LOAD(r15);
}

23
src/rt/arch/arm/gpr.h Normal file
View file

@ -0,0 +1,23 @@
// General-purpose registers. This structure is used during stack crawling.
#ifndef GPR_H
#define GPR_H
#include "rust_gpr_base.h"
class rust_gpr : public rust_gpr_base {
public:
uintptr_t r0, r1, r2, r3, r4, r5, r6, r7;
uintptr_t r8, r9, r10, r11, r12, r13, r14, r15;
inline uintptr_t get_fp() { return r11; }
inline uintptr_t get_ip() { return r12; }
inline void set_fp(uintptr_t new_fp) { r11 = new_fp; }
inline void set_ip(uintptr_t new_ip) { r12 = new_ip; }
void load();
};
#endif

View file

@ -0,0 +1,61 @@
.text
.code 32
.arm
.align
.globl record_sp_limit
.globl get_sp_limit
.globl get_sp
record_sp_limit:
mov r3, r0
ldr r0, =my_cpu
mov r1, #0
mov r2, #0
stmfd sp!, {r3, r7}
ldr r7, =345
swi #0
ldmfd sp!, {r3, r7}
movs r0, r0
movmi r0, #0
ldr r1, =my_array
str r3, [r1, r0]
mov pc, lr
get_sp_limit:
ldr r0, =my_cpu
mov r1, #0
mov r2, #0
stmfd sp!, {r4, r7}
ldr r7, =345
swi #0
ldmfd sp!, {r4, r7}
movs r0, r0
movmi r0, #0
mov r3, r0
ldr r1, =my_array
ldr r0, [r1, r3]
mov pc, lr
get_sp:
mov r0, sp
mov pc, lr
.data
my_cpu: .long 0
.global my_array
my_array:
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.end

21
src/rt/arch/arm/regs.h Normal file
View file

@ -0,0 +1,21 @@
#define RUSTRT_RBX 0
#define RUSTRT_RSP 1
#define RUSTRT_RBP 2
// RCX on Windows, RDI elsewhere
#define RUSTRT_ARG0 3
#define RUSTRT_R12 4
#define RUSTRT_R13 5
#define RUSTRT_R14 6
#define RUSTRT_R15 7
#define RUSTRT_IP 8
#define RUSTRT_MAX 32
// ARG0 is the register in which the first argument goes.
// Naturally this depends on your operating system.
# define RUSTRT_ARG0_S r0
# define RUSTRT_ARG1_S r1
# define RUSTRT_ARG2_S r2
# define RUSTRT_ARG3_S r3

View file

@ -0,0 +1,61 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "rust_android_dummy.h"
#include <math.h>
#ifdef __ANDROID__
int backtrace(void **array, int size) { return 0; }
char **backtrace_symbols(void *const *array, int size) { return 0; }
void backtrace_symbols_fd (void *const *array, int size, int fd) {}
extern "C" float log2f(float f)
{
return logf( f ) / logf( 2 );
}
extern "C" double log2( double n )
{
return log( n ) / log( 2 );
}
extern "C" void telldir()
{
}
extern "C" void seekdir()
{
}
extern "C" void mkfifo()
{
}
extern "C" void abs()
{
}
extern "C" void labs()
{
}
extern "C" void rand()
{
}
extern "C" void srand()
{
}
extern "C" void atof()
{
}
extern "C" void tgammaf()
{
}
#endif

View file

@ -0,0 +1,5 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "execinfo.h"

View file

@ -33,6 +33,27 @@
extern char **environ; extern char **environ;
#endif #endif
#ifdef __ANDROID__
time_t
timegm(struct tm *tm)
{
time_t ret;
char *tz;
tz = getenv("TZ");
setenv("TZ", "", 1);
tzset();
ret = mktime(tm);
if (tz)
setenv("TZ", tz, 1);
else
unsetenv("TZ");
tzset();
return ret;
}
#endif
extern "C" CDECL rust_str* extern "C" CDECL rust_str*
last_os_error() { last_os_error() {
rust_task *task = rust_get_current_task(); rust_task *task = rust_get_current_task();

View file

@ -28,6 +28,7 @@ rust_sched_loop::rust_sched_loop(rust_scheduler *sched, int id, bool killed) :
id(id), id(id),
should_exit(false), should_exit(false),
cached_c_stack(NULL), cached_c_stack(NULL),
extra_c_stack(NULL),
dead_task(NULL), dead_task(NULL),
killed(killed), killed(killed),
pump_signal(NULL), pump_signal(NULL),

View file

@ -165,6 +165,9 @@
#define RED_ZONE_SIZE RZ_BSD_64 #define RED_ZONE_SIZE RZ_BSD_64
#endif #endif
#endif #endif
#ifdef __ANDROID__
#define RED_ZONE_SIZE RZ_MAC_32
#endif
struct rust_box; struct rust_box;

View file

@ -91,6 +91,12 @@ void LLVMInitializeX86TargetMC();
void LLVMInitializeX86AsmPrinter(); void LLVMInitializeX86AsmPrinter();
void LLVMInitializeX86AsmParser(); void LLVMInitializeX86AsmParser();
void LLVMInitializeARMTargetInfo();
void LLVMInitializeARMTarget();
void LLVMInitializeARMTargetMC();
void LLVMInitializeARMAsmPrinter();
void LLVMInitializeARMAsmParser();
// Only initialize the platforms supported by Rust here, // Only initialize the platforms supported by Rust here,
// because using --llvm-root will have multiple platforms // because using --llvm-root will have multiple platforms
// that rustllvm doesn't actually link to and it's pointless to put target info // that rustllvm doesn't actually link to and it's pointless to put target info
@ -102,6 +108,12 @@ void LLVMRustInitializeTargets() {
LLVMInitializeX86TargetMC(); LLVMInitializeX86TargetMC();
LLVMInitializeX86AsmPrinter(); LLVMInitializeX86AsmPrinter();
LLVMInitializeX86AsmParser(); LLVMInitializeX86AsmParser();
LLVMInitializeARMTargetInfo();
LLVMInitializeARMTarget();
LLVMInitializeARMTargetMC();
LLVMInitializeARMAsmPrinter();
LLVMInitializeARMAsmParser();
} }
// Custom memory manager for MCJITting. It needs special features // Custom memory manager for MCJITting. It needs special features

View file

@ -383,19 +383,19 @@ LLVMInitializeInstCombine
LLVMInitializeScalarOpts LLVMInitializeScalarOpts
LLVMInitializeTarget LLVMInitializeTarget
LLVMInitializeTransformUtils LLVMInitializeTransformUtils
LLVMInitializeARMAsmLexer
LLVMInitializeX86AsmLexer LLVMInitializeX86AsmLexer
LLVMInitializeX86AsmLexer LLVMInitializeARMAsmParser
LLVMInitializeX86AsmParser
LLVMInitializeX86AsmParser LLVMInitializeX86AsmParser
LLVMInitializeARMAsmPrinter
LLVMInitializeX86AsmPrinter LLVMInitializeX86AsmPrinter
LLVMInitializeX86AsmPrinter LLVMInitializeARMDisassembler
LLVMInitializeX86Disassembler
LLVMInitializeX86Disassembler LLVMInitializeX86Disassembler
LLVMInitializeARMTarget
LLVMInitializeX86Target LLVMInitializeX86Target
LLVMInitializeX86Target LLVMInitializeARMTargetMC
LLVMInitializeX86TargetMC LLVMInitializeX86TargetMC
LLVMInitializeX86TargetMC LLVMInitializeARMTargetInfo
LLVMInitializeX86TargetInfo
LLVMInitializeX86TargetInfo LLVMInitializeX86TargetInfo
LLVMInsertBasicBlock LLVMInsertBasicBlock
LLVMInsertBasicBlockInContext LLVMInsertBasicBlockInContext