Skip to content

Commit 6c96d1e

Browse files
Don't rely on JSON symtabs for --gen-c, --function (rust-lang#2221)
1 parent cf26447 commit 6c96d1e

File tree

5 files changed

+31
-23
lines changed

5 files changed

+31
-23
lines changed

kani-compiler/src/codegen_cprover_gotoc/compiler_interface.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ impl CodegenBackend for GotocCodegenBackend {
159159
// Print compilation report.
160160
print_report(&gcx, tcx);
161161

162+
// Map from name to prettyName for all symbols
163+
let pretty_name_map: BTreeMap<InternedString, Option<InternedString>> =
164+
BTreeMap::from_iter(gcx.symbol_table.iter().map(|(k, s)| (*k, s.pretty_name)));
165+
162166
// Map MIR types to GotoC types
163167
let type_map: BTreeMap<InternedString, InternedString> =
164168
BTreeMap::from_iter(gcx.type_map.iter().map(|(k, v)| (*k, v.to_string().into())));
@@ -177,6 +181,7 @@ impl CodegenBackend for GotocCodegenBackend {
177181
let outputs = tcx.output_filenames(());
178182
let base_filename = outputs.output_path(OutputType::Object);
179183
let pretty = self.queries.lock().unwrap().get_output_pretty_json();
184+
write_file(&base_filename, ArtifactType::PrettyNameMap, &pretty_name_map, pretty);
180185
write_file(&base_filename, ArtifactType::SymTab, &gcx.symbol_table, pretty);
181186
write_file(&base_filename, ArtifactType::TypeMap, &type_map, pretty);
182187
write_file(&base_filename, ArtifactType::Metadata, &metadata, pretty);

kani-driver/src/call_cargo.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ pub struct CargoOutputs {
2929
/// The directory where compiler outputs should be directed.
3030
/// Usually 'target/BUILD_TRIPLE/debug/deps/'
3131
pub outdir: PathBuf,
32-
/// The collection of *.symtab.json files written.
33-
pub symtabs: Vec<PathBuf>,
32+
/// The collection of *.symtab.out goto binary files written.
33+
pub symtab_gotos: Vec<PathBuf>,
3434
/// The location of vtable restrictions files (a directory of *.restrictions.json)
3535
pub restrictions: Option<PathBuf>,
3636
/// The kani-metadata.json files written by kani-compiler.
@@ -129,7 +129,7 @@ impl KaniSession {
129129

130130
Ok(CargoOutputs {
131131
outdir: outdir.clone(),
132-
symtabs: glob(&outdir.join("*.symtab.json"))?,
132+
symtab_gotos: glob(&outdir.join("*.symtab.out"))?,
133133
metadata: glob(&outdir.join("*.kani-metadata.json"))?,
134134
restrictions: self.args.restrict_vtable().then_some(outdir),
135135
cargo_metadata: metadata,

kani-driver/src/call_goto_instrument.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ impl KaniSession {
5757
}
5858

5959
let c_demangled = alter_extension(output, "demangled.c");
60-
let symtab = project.get_harness_artifact(&harness, ArtifactType::SymTab).unwrap();
61-
self.demangle_c(symtab, &c_outfile, &c_demangled)?;
60+
let prett_name_map =
61+
project.get_harness_artifact(&harness, ArtifactType::PrettyNameMap).unwrap();
62+
self.demangle_c(prett_name_map, &c_outfile, &c_demangled)?;
6263
if !self.args.quiet {
6364
println!("Demangled GotoC code written to {}", c_demangled.to_string_lossy())
6465
}
@@ -165,22 +166,21 @@ impl KaniSession {
165166
/// For local variables, it would be more complicated than a simple search and replace to obtain the demangled name.
166167
pub fn demangle_c(
167168
&self,
168-
symtab_file: &impl AsRef<Path>,
169+
pretty_name_map_file: &impl AsRef<Path>,
169170
c_file: &Path,
170171
demangled_file: &Path,
171172
) -> Result<()> {
172173
let mut c_code = std::fs::read_to_string(c_file)?;
173-
let reader = BufReader::new(File::open(symtab_file)?);
174-
let symtab: serde_json::Value = serde_json::from_reader(reader)?;
175-
for (_, symbol) in symtab["symbolTable"].as_object().unwrap() {
176-
if let Some(serde_json::Value::String(name)) = symbol.get("name") {
177-
if let Some(serde_json::Value::String(pretty)) = symbol.get("prettyName") {
178-
// Struct names start with "tag-", but this prefix is not used in the GotoC files, so we strip it.
179-
// If there is no such prefix, we leave the name unchanged.
180-
let name = name.strip_prefix("tag-").unwrap_or(name);
181-
if !pretty.is_empty() && pretty != name {
182-
c_code = c_code.replace(name, pretty);
183-
}
174+
let reader = BufReader::new(File::open(pretty_name_map_file)?);
175+
let value: serde_json::Value = serde_json::from_reader(reader)?;
176+
let pretty_name_map = value.as_object().unwrap();
177+
for (name, pretty_name) in pretty_name_map {
178+
if let Some(pretty_name) = pretty_name.as_str() {
179+
// Struct names start with "tag-", but this prefix is not used in the GotoC files, so we strip it.
180+
// If there is no such prefix, we leave the name unchanged.
181+
let name = name.strip_prefix("tag-").unwrap_or(name);
182+
if !pretty_name.is_empty() && pretty_name != name {
183+
c_code = c_code.replace(name, pretty_name);
184184
}
185185
}
186186
}

kani-driver/src/project.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,8 @@ pub fn cargo_project(session: &KaniSession) -> Result<Project> {
155155
// Merge goto files.
156156
let joined_name = "cbmc-linked";
157157
let base_name = outdir.join(joined_name);
158-
let symtab_gotos: Vec<_> =
159-
outputs.symtabs.iter().map(|p| convert_type(p, SymTab, SymTabGoto)).collect();
160158
let goto = base_name.with_extension(Goto);
161-
session.link_goto_binary(&symtab_gotos, &goto)?;
159+
session.link_goto_binary(&outputs.symtab_gotos, &goto)?;
162160
artifacts.push(Artifact::try_new(&goto, Goto)?);
163161

164162
// Merge metadata files.
@@ -227,8 +225,8 @@ struct StandaloneProjectBuilder<'a> {
227225
}
228226

229227
/// All the type of artifacts that may be generated as part of the build.
230-
const BUILD_ARTIFACTS: [ArtifactType; 6] =
231-
[Metadata, Goto, SymTab, SymTabGoto, TypeMap, VTableRestriction];
228+
const BUILD_ARTIFACTS: [ArtifactType; 7] =
229+
[Metadata, Goto, SymTab, SymTabGoto, TypeMap, VTableRestriction, PrettyNameMap];
232230

233231
impl<'a> StandaloneProjectBuilder<'a> {
234232
/// Create a `StandaloneProjectBuilder` from the given input and session.

kani_metadata/src/artifact.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ pub enum ArtifactType {
2222
/// A `json` file that has information about the function pointer restrictions derived from
2323
/// vtable generation.
2424
VTableRestriction,
25+
/// A `json` file that stores the name to prettyName mapping for symbols
26+
/// (used to demangle names from the C dump).
27+
PrettyNameMap,
2528
}
2629

2730
impl ArtifactType {
@@ -33,6 +36,7 @@ impl ArtifactType {
3336
ArtifactType::SymTabGoto => "symtab.out",
3437
ArtifactType::TypeMap => "type_map.json",
3538
ArtifactType::VTableRestriction => "restrictions.json",
39+
ArtifactType::PrettyNameMap => "pretty_name_map.json",
3640
}
3741
}
3842
}
@@ -59,7 +63,8 @@ pub fn convert_type(path: &Path, from: ArtifactType, to: ArtifactType) -> PathBu
5963
| ArtifactType::SymTab
6064
| ArtifactType::SymTabGoto
6165
| ArtifactType::TypeMap
62-
| ArtifactType::VTableRestriction => {
66+
| ArtifactType::VTableRestriction
67+
| ArtifactType::PrettyNameMap => {
6368
result.set_extension("");
6469
result.set_extension(&to);
6570
}

0 commit comments

Comments
 (0)