Skip to content

Commit c87ea84

Browse files
committed
coverage-dump: Make filenames available to covfun record dumping
Actually printing the filenames is deferred to a subsequent commit that will simultaneously bless all affected tests.
1 parent aaac504 commit c87ea84

File tree

94 files changed

+394
-310
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+394
-310
lines changed

src/tools/coverage-dump/src/covfun.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ use std::collections::HashMap;
22
use std::fmt::{self, Debug, Write as _};
33
use std::sync::LazyLock;
44

5-
use anyhow::{Context, anyhow, ensure};
5+
use anyhow::{Context, anyhow, bail, ensure};
66
use itertools::Itertools;
77
use regex::Regex;
88

9+
use crate::covmap::FilenameTables;
910
use crate::llvm_junk::unescape_llvm_string_contents;
1011
use crate::parser::Parser;
1112

@@ -14,6 +15,7 @@ mod tests;
1415

1516
pub(crate) fn dump_covfun_mappings(
1617
llvm_ir: &str,
18+
filename_tables: &FilenameTables,
1719
function_names: &HashMap<u64, String>,
1820
) -> anyhow::Result<()> {
1921
// Extract function coverage entries from the LLVM IR assembly, and associate
@@ -49,8 +51,13 @@ pub(crate) fn dump_covfun_mappings(
4951
println!("Number of files: {num_files}");
5052

5153
for i in 0..num_files {
52-
let global_file_id = parser.read_uleb128_u32()?;
53-
println!("- file {i} => global file {global_file_id}");
54+
let global_file_id = parser.read_uleb128_usize()?;
55+
let &CovfunLineData { filenames_hash, .. } = line_data;
56+
#[expect(unused)] // Removed later in this PR.
57+
let Some(filename) = filename_tables.lookup(filenames_hash, global_file_id) else {
58+
bail!("couldn't resolve global file: {filenames_hash}, {global_file_id}");
59+
};
60+
println!("- file {i} => {global_file_id}");
5461
}
5562

5663
let num_expressions = parser.read_uleb128_u32()?;

src/tools/coverage-dump/src/covmap.rs

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use std::collections::HashMap;
2+
use std::sync::LazyLock;
3+
4+
use anyhow::{Context, ensure};
5+
use regex::Regex;
6+
7+
use crate::llvm_junk::{truncated_md5, unescape_llvm_string_contents};
8+
use crate::parser::Parser;
9+
10+
#[derive(Debug, Default)]
11+
pub(crate) struct FilenameTables {
12+
map: HashMap<u64, Vec<String>>,
13+
}
14+
15+
impl FilenameTables {
16+
pub(crate) fn lookup(&self, filenames_hash: u64, global_file_id: usize) -> Option<&str> {
17+
let table = self.map.get(&filenames_hash)?;
18+
let filename = table.get(global_file_id)?;
19+
Some(filename)
20+
}
21+
}
22+
23+
struct CovmapLineData {
24+
payload: Vec<u8>,
25+
}
26+
27+
pub(crate) fn make_filename_tables(llvm_ir: &str) -> anyhow::Result<FilenameTables> {
28+
let mut map = HashMap::default();
29+
30+
for line in llvm_ir.lines().filter(|line| is_covmap_line(line)) {
31+
let CovmapLineData { payload } = parse_covmap_line(line)?;
32+
33+
let mut parser = Parser::new(&payload);
34+
let n_filenames = parser.read_uleb128_usize()?;
35+
let uncompressed_bytes = parser.read_chunk_to_uncompressed_bytes()?;
36+
parser.ensure_empty()?;
37+
38+
let mut filenames_table = vec![];
39+
40+
let mut parser = Parser::new(&uncompressed_bytes);
41+
for _ in 0..n_filenames {
42+
let len = parser.read_uleb128_usize()?;
43+
let bytes = parser.read_n_bytes(len)?;
44+
let filename = str::from_utf8(bytes)?;
45+
filenames_table.push(filename.to_owned());
46+
}
47+
48+
let filenames_hash = truncated_md5(&payload);
49+
map.insert(filenames_hash, filenames_table);
50+
}
51+
52+
Ok(FilenameTables { map })
53+
}
54+
55+
fn is_covmap_line(line: &str) -> bool {
56+
line.starts_with("@__llvm_coverage_mapping ")
57+
}
58+
59+
fn parse_covmap_line(line: &str) -> anyhow::Result<CovmapLineData> {
60+
ensure!(is_covmap_line(line));
61+
62+
const RE_STRING: &str = r#"(?x)^
63+
@__llvm_coverage_mapping \ =
64+
.*
65+
\[ [0-9]+ \ x \ i8 \] \ c"(?<payload>[^"]*)"
66+
.*$
67+
"#;
68+
static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(RE_STRING).unwrap());
69+
70+
let captures =
71+
RE.captures(line).with_context(|| format!("couldn't parse covmap line: {line:?}"))?;
72+
let payload = unescape_llvm_string_contents(&captures["payload"]);
73+
74+
Ok(CovmapLineData { payload })
75+
}

src/tools/coverage-dump/src/main.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod covfun;
2+
mod covmap;
23
mod llvm_junk;
34
mod parser;
45
mod prf_names;
@@ -18,8 +19,9 @@ fn main() -> anyhow::Result<()> {
1819
let llvm_ir_path = args.get(1).context("LLVM IR file not specified")?;
1920
let llvm_ir = std::fs::read_to_string(llvm_ir_path).context("couldn't read LLVM IR file")?;
2021

22+
let filename_tables = covmap::make_filename_tables(&llvm_ir)?;
2123
let function_names = crate::prf_names::make_function_names_table(&llvm_ir)?;
22-
crate::covfun::dump_covfun_mappings(&llvm_ir, &function_names)?;
24+
crate::covfun::dump_covfun_mappings(&llvm_ir, &filename_tables, &function_names)?;
2325

2426
Ok(())
2527
}

tests/coverage/abort.cov-map

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Function name: abort::main
22
Raw bytes (83): 0x[01, 01, 07, 05, 01, 05, 0b, 01, 09, 05, 13, 01, 0d, 05, 1b, 01, 11, 0d, 01, 0d, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 19, 09, 00, 1a, 02, 0a, 06, 02, 09, 00, 0a, 02, 02, 0c, 00, 19, 0d, 00, 1a, 00, 31, 0e, 00, 30, 00, 31, 02, 04, 0c, 00, 19, 11, 00, 1a, 00, 31, 16, 00, 30, 00, 31, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
33
Number of files: 1
4-
- file 0 => global file 1
4+
- file 0 => 1
55
Number of expressions: 7
66
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
77
- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
@@ -36,7 +36,7 @@ Highest counter ID seen: c4
3636
Function name: abort::might_abort
3737
Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 03, 01, 01, 14, 05, 02, 09, 01, 0f, 02, 02, 0c, 03, 02]
3838
Number of files: 1
39-
- file 0 => global file 1
39+
- file 0 => 1
4040
Number of expressions: 1
4141
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
4242
Number of file 0 mappings: 3

tests/coverage/assert-ne.cov-map

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Function name: assert_ne::main
22
Raw bytes (28): 0x[01, 01, 02, 01, 05, 01, 09, 04, 01, 08, 01, 03, 15, 05, 04, 0d, 00, 13, 02, 02, 0d, 00, 13, 06, 03, 05, 01, 02]
33
Number of files: 1
4-
- file 0 => global file 1
4+
- file 0 => 1
55
Number of expressions: 2
66
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
77
- expression 1 operands: lhs = Counter(0), rhs = Counter(2)

tests/coverage/assert.cov-map

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Function name: assert::main
22
Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 09, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
33
Number of files: 1
4-
- file 0 => global file 1
4+
- file 0 => 1
55
Number of expressions: 6
66
- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
77
- expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add)
@@ -28,7 +28,7 @@ Highest counter ID seen: c3
2828
Function name: assert::might_fail_assert
2929
Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 02, 0f, 02, 02, 25, 00, 3d, 05, 01, 01, 00, 02]
3030
Number of files: 1
31-
- file 0 => global file 1
31+
- file 0 => 1
3232
Number of expressions: 1
3333
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
3434
Number of file 0 mappings: 3

tests/coverage/assert_not.cov-map

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Function name: assert_not::main
22
Raw bytes (29): 0x[01, 01, 00, 05, 01, 06, 01, 01, 11, 01, 02, 05, 00, 13, 01, 01, 05, 00, 13, 01, 01, 05, 00, 15, 01, 01, 01, 00, 02]
33
Number of files: 1
4-
- file 0 => global file 1
4+
- file 0 => 1
55
Number of expressions: 0
66
Number of file 0 mappings: 5
77
- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 17)

0 commit comments

Comments
 (0)