Merge changes from topic "vmbase_logger"

* changes:
  vmbase/pvmfw: Extract common build properties to defaults
  vmbase/pvmfw: Remove unnecessary 'stem' properties
  vmbase: Use logger in example kernel
  vmbase: Add basic logger
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index 4fcde74..fb639d8 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -5,57 +5,35 @@
 rust_ffi_static {
     name: "libpvmfw",
     crate_name: "pvmfw",
+    defaults: ["vmbase_ffi_defaults"],
     srcs: ["src/main.rs"],
     edition: "2021",
-    no_stdlibs: true,
-    stdlibs: [
-        "libcompiler_builtins.rust_sysroot",
-        "libcore.rust_sysroot",
-    ],
     rustlibs: [
         "libvmbase",
     ],
-    enabled: false,
-    target: {
-        android_arm64: {
-            enabled: true,
-        },
-    },
     apex_available: ["com.android.virt"],
 }
 
 cc_binary {
     name: "pvmfw_elf",
     stem: "pvmfw",
+    defaults: ["vmbase_elf_defaults"],
     srcs: [
         "idmap.S",
     ],
     static_libs: [
         "libpvmfw",
-        "libvmbase_entry",
     ],
-    static_executable: true,
-    nocrt: true,
-    system_shared_libs: ["libc"],
-    stl: "none",
     linker_scripts: [
         "image.ld",
         ":vmbase_sections",
     ],
-    installable: false,
-    enabled: false,
-    target: {
-        android_arm64: {
-            enabled: true,
-        },
-    },
     apex_available: ["com.android.virt"],
 }
 
 raw_binary {
     name: "pvmfw",
     src: ":pvmfw_elf",
-    stem: "pvmfw.bin",
     enabled: false,
     target: {
         android_arm64: {
diff --git a/vmbase/Android.bp b/vmbase/Android.bp
index e88420e..e098ea7 100644
--- a/vmbase/Android.bp
+++ b/vmbase/Android.bp
@@ -2,41 +2,76 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-rust_library_rlib {
-    name: "libvmbase",
+rust_defaults {
+    name: "vmbase_rust_defaults",
     host_supported: false,
-    crate_name: "vmbase",
-    srcs: ["src/lib.rs"],
-    edition: "2021",
-    rustlibs: [
-        "libpsci",
-        "libspin_nostd",
-    ],
     enabled: false,
     target: {
         android_arm64: {
             enabled: true,
         },
     },
+}
+
+rust_defaults {
+    name: "vmbase_ffi_defaults",
+    defaults: ["vmbase_rust_defaults"],
+    no_stdlibs: true,
+    stdlibs: [
+        "libcompiler_builtins.rust_sysroot",
+        "libcore.rust_sysroot",
+    ],
+}
+
+cc_defaults {
+    name: "vmbase_cc_defaults",
+    nocrt: true,
+    system_shared_libs: [],
+    stl: "none",
+    installable: false,
+    enabled: false,
+    target: {
+        android_arm64: {
+            enabled: true,
+        },
+    },
+    sanitize: {
+        hwaddress: false,
+    },
+}
+
+cc_defaults {
+    name: "vmbase_elf_defaults",
+    defaults: ["vmbase_cc_defaults"],
+    system_shared_libs: ["libc"],
+    static_executable: true,
+    static_libs: [
+        "libvmbase_entry",
+    ],
+}
+
+rust_library_rlib {
+    name: "libvmbase",
+    defaults: ["vmbase_rust_defaults"],
+    crate_name: "vmbase",
+    srcs: ["src/lib.rs"],
+    edition: "2021",
+    rustlibs: [
+        "liblog_rust_nostd",
+        "libpsci",
+        "libspin_nostd",
+    ],
     apex_available: ["com.android.virt"],
 }
 
 cc_library_static {
     name: "libvmbase_entry",
+    defaults: ["vmbase_cc_defaults"],
     srcs: [
         "entry.S",
         "exceptions.S",
     ],
-    nocrt: true,
     no_libcrt: true,
-    system_shared_libs: [],
-    stl: "none",
-    enabled: false,
-    target: {
-        android_arm64: {
-            enabled: true,
-        },
-    },
     apex_available: ["com.android.virt"],
 }
 
diff --git a/vmbase/example/Android.bp b/vmbase/example/Android.bp
index c75820c..e11bb2f 100644
--- a/vmbase/example/Android.bp
+++ b/vmbase/example/Android.bp
@@ -4,63 +4,39 @@
 
 rust_ffi_static {
     name: "libvmbase_example",
+    defaults: ["vmbase_ffi_defaults"],
     crate_name: "vmbase_example",
     srcs: ["src/main.rs"],
     edition: "2021",
-    no_stdlibs: true,
-    stdlibs: [
-        "libcompiler_builtins.rust_sysroot",
-        "libcore.rust_sysroot",
-    ],
     rustlibs: [
         "libaarch64_paging",
         "libbuddy_system_allocator",
+        "liblog_rust_nostd",
         "libvmbase",
     ],
-    enabled: false,
-    target: {
-        android_arm64: {
-            enabled: true,
-        },
-    },
     apex_available: ["com.android.virt"],
 }
 
 cc_binary {
     name: "vmbase_example_elf",
     stem: "vmbase_example",
+    defaults: ["vmbase_elf_defaults"],
     srcs: [
         "idmap.S",
     ],
     static_libs: [
-        "libvmbase_entry",
         "libvmbase_example",
     ],
-    static_executable: true,
-    nocrt: true,
-    system_shared_libs: ["libc"],
-    stl: "none",
     linker_scripts: [
         "image.ld",
         ":vmbase_sections",
     ],
-    installable: false,
-    enabled: false,
-    target: {
-        android_arm64: {
-            enabled: true,
-        },
-    },
-    sanitize: {
-        hwaddress: false,
-    },
     apex_available: ["com.android.virt"],
 }
 
 raw_binary {
     name: "vmbase_example",
     src: ":vmbase_example_elf",
-    stem: "vmbase_example.bin",
     enabled: false,
     target: {
         android_arm64: {
diff --git a/vmbase/example/src/main.rs b/vmbase/example/src/main.rs
index 6b110cf..3c91f97 100644
--- a/vmbase/example/src/main.rs
+++ b/vmbase/example/src/main.rs
@@ -29,7 +29,8 @@
 use aarch64_paging::{idmap::IdMap, paging::Attributes};
 use alloc::{vec, vec::Vec};
 use buddy_system_allocator::LockedHeap;
-use vmbase::{main, println};
+use log::{info, LevelFilter};
+use vmbase::{logger, main, println};
 
 static INITIALISED_DATA: [u32; 4] = [1, 2, 3, 4];
 static mut ZEROED_DATA: [u32; 10] = [0; 10];
@@ -47,8 +48,10 @@
 
 /// Entry point for VM bootloader.
 pub fn main(arg0: u64, arg1: u64, arg2: u64, arg3: u64) {
+    logger::init(LevelFilter::Debug).unwrap();
+
     println!("Hello world");
-    println!("x0={:#018x}, x1={:#018x}, x2={:#018x}, x3={:#018x}", arg0, arg1, arg2, arg3);
+    info!("x0={:#018x}, x1={:#018x}, x2={:#018x}, x3={:#018x}", arg0, arg1, arg2, arg3);
     print_addresses();
     assert_eq!(arg0, dtb_range().start.0 as u64);
     check_data();
@@ -83,20 +86,20 @@
         )
         .unwrap();
 
-    println!("Activating IdMap...");
-    println!("{:?}", idmap);
+    info!("Activating IdMap...");
+    info!("{:?}", idmap);
     idmap.activate();
-    println!("Activated.");
+    info!("Activated.");
 
     check_data();
 }
 
 fn check_data() {
-    println!("INITIALISED_DATA: {:#010x}", &INITIALISED_DATA as *const u32 as usize);
+    info!("INITIALISED_DATA: {:#010x}", &INITIALISED_DATA as *const u32 as usize);
     unsafe {
-        println!("ZEROED_DATA: {:#010x}", &ZEROED_DATA as *const u32 as usize);
-        println!("MUTABLE_DATA: {:#010x}", &MUTABLE_DATA as *const u32 as usize);
-        println!("HEAP: {:#010x}", &HEAP as *const u8 as usize);
+        info!("ZEROED_DATA: {:#010x}", &ZEROED_DATA as *const u32 as usize);
+        info!("MUTABLE_DATA: {:#010x}", &MUTABLE_DATA as *const u32 as usize);
+        info!("HEAP: {:#010x}", &HEAP as *const u8 as usize);
     }
 
     assert_eq!(INITIALISED_DATA[0], 1);
@@ -122,11 +125,11 @@
         MUTABLE_DATA[0] -= 41;
         assert_eq!(MUTABLE_DATA[0], 1);
     }
-    println!("Data looks good");
+    info!("Data looks good");
 }
 
 fn check_alloc() {
-    println!("Allocating a Vec...");
+    info!("Allocating a Vec...");
     let mut vector: Vec<u32> = vec![1, 2, 3, 4];
     assert_eq!(vector[0], 1);
     assert_eq!(vector[1], 2);
@@ -134,5 +137,5 @@
     assert_eq!(vector[3], 4);
     vector[2] = 42;
     assert_eq!(vector[2], 42);
-    println!("Vec seems to work.");
+    info!("Vec seems to work.");
 }
diff --git a/vmbase/src/lib.rs b/vmbase/src/lib.rs
index 90d6fc2..257f415 100644
--- a/vmbase/src/lib.rs
+++ b/vmbase/src/lib.rs
@@ -18,6 +18,7 @@
 
 pub mod console;
 mod entry;
+pub mod logger;
 pub mod power;
 pub mod uart;
 
diff --git a/vmbase/src/logger.rs b/vmbase/src/logger.rs
new file mode 100644
index 0000000..5f0f1c2
--- /dev/null
+++ b/vmbase/src/logger.rs
@@ -0,0 +1,46 @@
+// Copyright 2022, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Logger for vmbase.
+//!
+//! Internally uses the println! vmbase macro, which prints to crosvm's UART.
+//! Note: may not work if the VM is in an inconsistent state. Exception handlers
+//! should avoid using this logger and instead print with eprintln!.
+
+extern crate log;
+
+use super::println;
+use log::{LevelFilter, Log, Metadata, Record, SetLoggerError};
+
+struct Logger;
+static LOGGER: Logger = Logger;
+
+impl Log for Logger {
+    fn enabled(&self, _metadata: &Metadata) -> bool {
+        true
+    }
+
+    fn log(&self, record: &Record) {
+        println!("[{}] {}", record.level(), record.args());
+    }
+
+    fn flush(&self) {}
+}
+
+/// Initialize vmbase logger with a given max logging level.
+pub fn init(max_level: LevelFilter) -> Result<(), SetLoggerError> {
+    log::set_logger(&LOGGER)?;
+    log::set_max_level(max_level);
+    Ok(())
+}