This is an automated email from the ASF dual-hosted git repository.

dingyu pushed a commit to branch fix-sgx-cov
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave-sgx-sdk.git

commit d0741963b623160eb3a8d99f92c69cc4861b1e0e
Author: Yu Ding <[email protected]>
AuthorDate: Mon Dec 28 21:14:55 2020 -0800

    fix sgx-cov to be compatible with LLVM 10 profiler API
---
 samplecode/sgx-cov/Makefile                  |   4 +-
 samplecode/sgx-cov/enclave/enclave-cov-rustc |   0
 samplecode/sgx-cov/enclave/llvm-gcov         |   2 +-
 samplecode/sgx-cov/enclave/src/lib.rs        |   3 +
 sgx_cov/lib.rs                               | 233 ++++++++++++++++-----------
 5 files changed, 141 insertions(+), 101 deletions(-)

diff --git a/samplecode/sgx-cov/Makefile b/samplecode/sgx-cov/Makefile
index f6aa06b..e5b9f63 100644
--- a/samplecode/sgx-cov/Makefile
+++ b/samplecode/sgx-cov/Makefile
@@ -160,8 +160,8 @@ enclave:
 
 .PHONY: gen_cov_html
 gen_cov_html:
-       lcov --gcov-tool $(PWD)/enclave/llvm-gcov --rc lcov_branch_coverage=1 
--rc lcov_excl_line=assert --capture --directory ${Target_Dir} -o ./all.tag.info
-       lcov --gcov-tool $(PWD)/enclave/llvm-gcov --rc lcov_branch_coverage=1 
--rc lcov_excl_line=assert --extract all.tag.info `find "$$(cd enclave/src; 
pwd)" -name "*.rs"` -o final.info
+       lcov --gcov-tool gcov --rc lcov_branch_coverage=1 --rc 
lcov_excl_line=assert --capture --directory ${Target_Dir} -o ./all.tag.info
+       lcov --gcov-tool gcov --rc lcov_branch_coverage=1 --rc 
lcov_excl_line=assert --extract all.tag.info `find "$$(cd enclave/src; pwd)" 
-name "*.rs"` -o final.info
        genhtml --branch-coverage --demangle-cpp --legend ./final.info -o 
./html/ --ignore-errors source
 
 .PHONY: clean
diff --git a/samplecode/sgx-cov/enclave/enclave-cov-rustc 
b/samplecode/sgx-cov/enclave/enclave-cov-rustc
old mode 100644
new mode 100755
diff --git a/samplecode/sgx-cov/enclave/llvm-gcov 
b/samplecode/sgx-cov/enclave/llvm-gcov
old mode 100644
new mode 100755
index 0191fd3..d5923e4
--- a/samplecode/sgx-cov/enclave/llvm-gcov
+++ b/samplecode/sgx-cov/enclave/llvm-gcov
@@ -1,2 +1,2 @@
 #!/bin/sh -e
-llvm-cov gcov $*
\ No newline at end of file
+llvm-cov gcov $*
diff --git a/samplecode/sgx-cov/enclave/src/lib.rs 
b/samplecode/sgx-cov/enclave/src/lib.rs
index 420a505..5af1431 100644
--- a/samplecode/sgx-cov/enclave/src/lib.rs
+++ b/samplecode/sgx-cov/enclave/src/lib.rs
@@ -99,5 +99,8 @@ pub extern "C" fn say_something(some_string: *const u8, 
some_len: usize) -> sgx_
     // Ocall to normal world for output
     println!("{}", &hello_string);
 
+    #[cfg(feature = "cov")]
+    sgx_cov::cov_writeout();
+
     sgx_status_t::SGX_SUCCESS
 }
diff --git a/sgx_cov/lib.rs b/sgx_cov/lib.rs
index 34b7dd0..5a21b51 100644
--- a/sgx_cov/lib.rs
+++ b/sgx_cov/lib.rs
@@ -45,9 +45,14 @@ use std::sync::{Once, SgxMutex};
 use std::untrusted::fs::{copy, File, OpenOptions};
 
 static INIT: Once = Once::new();
+const GCOV_DATA_MAGIC: u32 = 0x6763_6461;
+const GCOV_TAG_FUNCTION: u32 = 0x0100_0000;
+const GCOV_TAG_COUNTER_ARCS: u32 = 0x01a1_0000;
+const GCOV_TAG_OBJECT_SUMMARY: u32 = 0xa100_0000;
+const GCOV_TAG_PROGRAM_SUMMARY: u32 = 0xa300_0000;
 
 lazy_static! {
-    static ref GCDA_FILE: SgxMutex<c_int> = SgxMutex::new(-1);
+    static ref GCDA_FILE: SgxMutex<(c_int, c_int)> = SgxMutex::new((-1, -1));
     static ref WROUT_FNS: SgxMutex<Vec<extern "C" fn()>> = 
SgxMutex::new(Vec::new());
     static ref RND: SgxMutex<u32> = SgxMutex::new(0);
 }
@@ -59,7 +64,11 @@ pub fn cov_writeout() {
 }
 
 #[no_mangle]
-pub extern "C" fn llvm_gcov_init(writeout: extern "C" fn(), _flush: extern "C" 
fn()) {
+pub extern "C" fn llvm_gcov_init(
+    writeout: extern "C" fn(),
+    _flush: extern "C" fn(),
+    _reset: extern "C" fn(),
+) {
     INIT.call_once(|| {
         let mut rng = sgx_rand::thread_rng();
         let mut rnd = RND.lock().unwrap();
@@ -71,109 +80,89 @@ pub extern "C" fn llvm_gcov_init(writeout: extern "C" 
fn(), _flush: extern "C" f
 
 #[no_mangle]
 pub extern "C" fn llvm_gcda_summary_info() {
-    match GCDA_FILE.lock() {
-        Ok(fd) => {
-            let mut file = unsafe { File::from_raw_fd(*fd) };
-
-            let summary_tag: u32 = 0xa1;
-            file.write_all(&summary_tag.to_be_bytes()).unwrap();
-            let len: u32 = 9;
-            file.write_all(&len.to_le_bytes()).unwrap();
-            let zero: u32 = 0;
-            let one: u32 = 1;
-            file.write_all(&zero.to_le_bytes()).unwrap();
-            file.write_all(&zero.to_le_bytes()).unwrap();
-            file.write_all(&one.to_le_bytes()).unwrap();
-            for _ in 0..(len - 3) {
-                file.write_all(&zero.to_le_bytes()).unwrap();
+    GCDA_FILE
+        .lock()
+        .map_or_else(
+            |e| panic!("llvm_gcda_summary_info failed {:?}", e),
+            |tup| Ok((unsafe { File::from_raw_fd(tup.0) }, tup.1)),
+        )
+        .and_then(|(mut file, gcov_version)| {
+            if gcov_version >= 90 {
+                file.write_all(&GCOV_TAG_OBJECT_SUMMARY.to_le_bytes())?;
+                file.write_all(&(2 as u32).to_le_bytes())?;
+                file.write_all(&(1 as u32).to_le_bytes())?; // runs. we never 
merge so it's always 1
+                file.write_all(&(0 as u32).to_le_bytes())?; // sum_max
+            } else {
+                file.write_all(&GCOV_TAG_PROGRAM_SUMMARY.to_le_bytes())?;
+                file.write_all(&(3 as u32).to_le_bytes())?;
+                file.write_all(&(0 as u32).to_le_bytes())?;
+                file.write_all(&(0 as u32).to_le_bytes())?;
+                file.write_all(&(1 as u32).to_le_bytes())?; // runs. we never 
merge so it's always 1
             }
-            let prog_tag: u32 = 0xa3;
-            file.write_all(&prog_tag.to_be_bytes()).unwrap();
-            file.write_all(&zero.to_le_bytes()).unwrap();
-
-            // Prevent it from drop
             let _ = file.into_raw_fd();
-        }
-        Err(_) => panic!("llvm_gcda_emit_arcs failed"),
-    }
+            Ok(())
+        })
+        .unwrap_or_else(|e: std::io::Error| panic!("llvm_gcda_summary_info 
failed {:?}", e))
 }
 
 #[no_mangle]
 pub extern "C" fn llvm_gcda_emit_arcs(num_counters: u32, counters: *const u64) 
{
+    // we never merge
+    // so `counters` is no longer * mut u64
     let cnts = unsafe { slice::from_raw_parts(counters, num_counters as usize) 
};
-    match GCDA_FILE.lock() {
-        Ok(fd) => {
-            let mut file = unsafe { File::from_raw_fd(*fd) };
 
-            let arcs_tag: u32 = 0xa101;
-            file.write_all(&arcs_tag.to_be_bytes()).unwrap();
+    GCDA_FILE
+        .lock()
+        .map_or_else(
+            |e| panic!("llvm_gcda_emit_arcs failed {:?}", e),
+            |tup| Ok(unsafe { File::from_raw_fd(tup.0) }),
+        )
+        .and_then(|mut file| {
+            file.write_all(&GCOV_TAG_COUNTER_ARCS.to_le_bytes())?;
             let len: u32 = num_counters * 2;
-            file.write_all(&len.to_le_bytes()).unwrap();
-            for i in 0..num_counters {
-                file.write_all(&cnts[i as usize].to_le_bytes()).unwrap();
+            file.write_all(&len.to_le_bytes())?;
+            for c in cnts {
+                file.write_all(&c.to_le_bytes())?;
             }
-
-            // Prevent it from drop
             let _ = file.into_raw_fd();
-        }
-        Err(_) => panic!("llvm_gcda_emit_arcs failed"),
-    }
+            Ok(())
+        })
+        .unwrap_or_else(|e: std::io::Error| panic!("llvm_gcda_emit_arcs failed 
{:?}", e))
 }
 
 #[no_mangle]
-pub extern "C" fn llvm_gcda_emit_function(
-    ident: u32,
-    raw_func_name: *const c_char,
-    fchecksum: u32,
-    use_extra_checksum: u8,
-    cfg_checksum: u32,
-) {
-    let func_name_str: &CStr = unsafe { CStr::from_ptr(raw_func_name) };
-    let func_name = func_name_str.to_str().unwrap();
+pub extern "C" fn llvm_gcda_emit_function(ident: u32, func_checksum: u32, 
cfg_checksum: u32) {
     let mut len: u32 = 2;
-    if use_extra_checksum != 0 {
+    let use_extra_checksum: bool = GCDA_FILE.lock().map(|tup| tup.1 >= 
47).unwrap();
+
+    if use_extra_checksum {
         len += 1;
     }
-    let str_len = (1 + func_name.len() / 4) as u32;
-    len += str_len;
-
-    match GCDA_FILE.lock() {
-        Ok(fd) => {
-            let mut file = unsafe { File::from_raw_fd(*fd) };
-
-            let func_tag: u32 = 1;
-            file.write_all(&func_tag.to_be_bytes()).unwrap();
-            file.write_all(&len.to_le_bytes()).unwrap();
-            file.write_all(&ident.to_le_bytes()).unwrap();
-            file.write_all(&fchecksum.to_le_bytes()).unwrap();
-            if use_extra_checksum != 0 {
-                file.write_all(&cfg_checksum.to_le_bytes()).unwrap();
-            }
-            file.write_all(&str_len.to_le_bytes()).unwrap();
-            file.write_all(func_name.as_bytes()).unwrap();
 
-            let zero: u8 = 0;
-            let padding_size = 4 - func_name.len() % 4;
-            for _ in 0..padding_size {
-                file.write_all(&zero.to_le_bytes()).unwrap();
+    GCDA_FILE
+        .lock()
+        .map_or_else(
+            |e| panic!("llvm_gcda_emit_function failed {:?}", e),
+            |tup| Ok(unsafe { File::from_raw_fd(tup.0) }),
+        )
+        .and_then(|mut file| {
+            file.write_all(&GCOV_TAG_FUNCTION.to_le_bytes())?;
+            file.write_all(&len.to_le_bytes())?;
+            file.write_all(&ident.to_le_bytes())?;
+            file.write_all(&func_checksum.to_le_bytes())?;
+            if use_extra_checksum {
+                file.write_all(&cfg_checksum.to_le_bytes())?;
             }
-
-            // Prevent it from drop
             let _ = file.into_raw_fd();
-        }
-        Err(_) => panic!("llvm_gcda_emit_function failed"),
-    }
+            Ok(())
+        })
+        .unwrap_or_else(|e: std::io::Error| panic!("llvm_gcda_emit_function 
failed {:?}", e))
 }
 
 #[no_mangle]
-pub extern "C" fn llvm_gcda_start_file(
-    raw_file_name: *const c_char,
-    ver: *const u8,
-    checksum: u32,
-) {
-    let file_name_str: &CStr = unsafe { CStr::from_ptr(raw_file_name) };
+pub extern "C" fn llvm_gcda_start_file(orig_filename: *const c_char, version: 
u32, checksum: u32) {
+    let file_name_str: &CStr = unsafe { CStr::from_ptr(orig_filename) };
     let file_name = file_name_str.to_str().unwrap();
-    let version = unsafe { slice::from_raw_parts(ver, 4) };
 
     let mut prefix = String::from(file_name);
     prefix.truncate(file_name.len() - 5);
@@ -182,35 +171,83 @@ pub extern "C" fn llvm_gcda_start_file(
     let new_gcno_name = format!("{}.{:08x}.gcno", prefix, *rnd);
     let new_gcda_name = format!("{}.{:08x}.gcda", prefix, *rnd);
 
-    match GCDA_FILE.lock() {
-        Ok(mut fd) => {
-            copy(orig_gcno_name, new_gcno_name).unwrap();
+    GCDA_FILE
+        .lock()
+        .map_or_else(
+            |e| panic!("llvm_gcda_emit_function failed {:?}", e),
+            |tup| Ok(tup),
+        )
+        .and_then(|mut tup| {
+            copy(orig_gcno_name, new_gcno_name)?;
             let mut file = match OpenOptions::new()
                 .write(true)
                 .append(false)
                 .open(&new_gcda_name)
             {
                 Ok(file) => file,
-                Err(_) => File::create(&new_gcda_name).unwrap(),
+                Err(_) => File::create(&new_gcda_name)?,
+            };
+
+            let c3: u8 = ((version >> 24) & 0x000000FF) as u8;
+            let c2: u8 = ((version >> 16) & 0x000000FF) as u8;
+            let c1: u8 = ((version >> 8) & 0x000000FF) as u8;
+            let parsed_gcov_version: i32 = if c3 >= 'A' as u8 {
+                ((c3 - 'A' as u8) as i32) * 100
+                    + ((c2 - '0' as u8) as i32) * 10
+                    + (c1 - '0' as u8) as i32
+            } else {
+                ((c3 - '0' as u8) as i32) * 10 + (c1 - '0' as u8) as i32
             };
-            file.write_all(b"adcg").unwrap();
-            file.write_all(version).unwrap();
+
+            tup.1 = parsed_gcov_version;
+
+            file.write_all(&GCOV_DATA_MAGIC.to_le_bytes()).unwrap();
+            file.write_all(&parsed_gcov_version.to_le_bytes()).unwrap();
             file.write_all(&checksum.to_le_bytes()).unwrap();
-            *fd = file.into_raw_fd();
-        }
-        Err(_) => panic!("llvm_gcda_start_file failed!"),
-    }
+
+            tup.0 = file.into_raw_fd();
+
+            Ok(())
+        })
+        .unwrap_or_else(|e: std::io::Error| panic!("llvm_gcda_start_file 
failed {:?}", e))
 }
 
 #[no_mangle]
 pub extern "C" fn llvm_gcda_end_file() {
-    match GCDA_FILE.lock() {
-        Ok(fd) => {
-            let mut file = unsafe { File::from_raw_fd(*fd) };
-            let eof: u64 = 0;
-            file.write_all(&eof.to_be_bytes()).unwrap();
-            // Let it drop
+    if let Ok(ref tup) = GCDA_FILE.lock() {
+        let fd = &tup.0;
+        let mut file = unsafe { File::from_raw_fd(*fd) };
+        let eof: u64 = 0;
+        file.write_all(&eof.to_be_bytes()).unwrap();
+    // Let it drop
+    } else {
+        panic!("llvm_gcda_end_file failed!");
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn llvm_gcda_increment_indirect_counter(
+    predecessor: *mut u32,
+    counters: *mut *mut u64,
+) {
+    let counter: *mut u64;
+    let pred: u32;
+
+    if predecessor.is_null() || counters.is_null() {
+        return;
+    }
+
+    pred = unsafe { *predecessor };
+
+    if pred == 0xFFFF_FFFF {
+        return;
+    }
+
+    counter = unsafe { *counters.offset(pred as isize) };
+
+    if !counter.is_null() {
+        unsafe {
+            *counter = *counter + 1;
         }
-        Err(_) => panic!("llvm_gcda_end_file failed!"),
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to