libabigail
abg-fe-iface.cc
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2// -*- Mode: C++ -*-
3//
4// Copyright (C) 2022-2024 Red Hat, Inc.
5//
6// Author: Dodji Seketeli
7
8/// @file
9///
10/// This file contains the definitions of the the fe_iface base type.
11
12#include "abg-internal.h"
13// <headers defining libabigail's API go under here>
14ABG_BEGIN_EXPORT_DECLARATIONS
15
16#include "abg-corpus.h"
17#include "abg-fe-iface.h"
18
19ABG_END_EXPORT_DECLARATIONS
20// </headers defining libabigail's API>
21
22namespace abigail
23{
24
25/// The private data structure for the @ref fe_iface type.
26struct fe_iface::priv
27{
28 std::string corpus_path;
29 std::string dt_soname;
30 fe_iface::options_type options;
32 ir::corpus_sptr corpus;
33 ir::corpus_group_sptr corpus_group;
34
35 priv(const std::string& path, environment& e)
36 : corpus_path(path), options(e)
37 {
38 initialize();
39 }
40
41 /// This function resets the data of @ref fe_iface::priv data so
42 /// that it can be re-used again.
43 void
45 {
46 corpus_path.clear();
47 dt_soname.clear();
48 suppressions.clear();
49 corpus_group.reset();
50 corpus.reset();
51 }
52}; //end struct fe_iface::priv
53
54/// Constructor of the type @ref fe_iface::options_type.
55///
56/// @param e the environment used by the Front End Interface.
58 : env(e)
59{
60}
61
62/// Constructor of the type @ref fe_iface.
63///
64/// @param corpus_path the path to the file represented by the ABI
65/// corpus that is going to be built by this Front End.
66///
67/// @param e the environment in which the Front End operates.
69 : priv_(new priv(corpus_path, e))
70{
71}
72
73/// Desctructor of the Front End Interface.
75{delete priv_;}
76
77/// Re-initialize the current Front End.
78///
79/// @param corpus_path the path to the file for which a new corpus is
80/// to be created.
81void
82fe_iface::initialize(const std::string& corpus_path)
83{
84 priv_->initialize();
85 priv_->corpus_path = corpus_path;
86}
87
88/// Getter of the the options of the current Front End Interface.
89///
90/// @return the options of the current Front End Interface.
93{return priv_->options;}
94
95/// Getter of the the options of the current Front End Interface.
96///
97/// @return the options of the current Front End Interface.
100{return priv_->options;}
101
102/// Getter of the path to the file which an ABI corpus is to be
103/// created for.
104///
105/// @return the path to the file which an ABI corpus is to be created
106/// for.
107const std::string&
109{return priv_->corpus_path;}
110
111/// Setter of the path to the file which an ABI corpus is to be
112/// created for.
113///
114/// @param p the new path to the file which an ABI corpus is to be
115/// created for.
116void
117fe_iface::corpus_path(const std::string& p)
118{priv_->corpus_path = p;}
119
120/// Getter for the SONAME of the analyzed binary.
121///
122/// @return the SONAME of the analyzed binary.
123const string&
125{return priv_->dt_soname;}
126
127/// Getter for the SONAME of the analyzed binary.
128///
129/// @return the SONAME of the analyzed binary.
130void
131fe_iface::dt_soname(const string& soname)
132{priv_->dt_soname = soname;}
133
134/// Test if the input binary is to be considered as a Linux Kernel
135/// binary.
136///
137/// @return true iff the input binary is to be considered as a Linux
138/// Kernel binary.
139bool
141{return priv_->options.load_in_linux_kernel_mode;}
142
143/// Getter of the vector of suppression specifications associated with
144/// the current front-end.
145///
146/// @return the vector of suppression specifications associated with
147/// the current front-end.
150{return priv_->suppressions;}
151
152/// Getter of the vector of suppression specifications associated with
153/// the current front-end.
154///
155/// @return the vector of suppression specifications associated with
156/// the current front-end.
159{return priv_->suppressions;}
160
161/// Setter of the vector of suppression specifications associated with
162/// the current front-end.
163///
164/// @param supprs the new vector of suppression specifications
165/// associated with the current front-end.
166void
168{priv_->suppressions = supprs;}
169
170/// Add suppressions specifications to the set of suppressions to be
171/// used during the construction of the ABI internal representation
172/// (the ABI corpus) from the input file.
173///
174/// During the construction of the ABI corpus, ABI artifacts that
175/// match a given suppression specification are dropped on the floor;
176/// that is, they are discarded and won't be part of the final ABI
177/// corpus. This is a way to reduce the amount of data held by the
178/// final ABI corpus.
179///
180/// Note that the suppression specifications provided to this function
181/// are only considered during the construction of the ABI corpus.
182/// For instance, they are not taken into account during e.g
183/// comparisons of two ABI corpora that might happen later. If you
184/// want to apply suppression specificatins to the comparison (or
185/// reporting) of ABI corpora please refer to the documentation of the
186/// @ref diff_context type to learn how to set suppressions that are
187/// to be used in that context.
188///
189/// @param supprs the suppression specifications to be applied during
190/// the construction of the ABI corpus.
191void
193{
194 for (const auto& s : supprs)
195 if (s->get_drops_artifact_from_ir())
196 suppressions().push_back(s);
197}
198
199/// Getter for the ABI corpus being built by the current front-end.
200///
201/// @return the ABI corpus being built by the current front-end.
202corpus_sptr
204{
205 if (!priv_->corpus)
206 {
207 priv_->corpus = std::make_shared<ir::corpus>(options().env,
208 corpus_path());
209 }
210 return priv_->corpus;
211}
212
213/// Getter for the ABI corpus being built by the current front-end.
214///
215/// @return the ABI corpus being built by the current front-end.
216const corpus_sptr
218{return const_cast<fe_iface*>(this)->corpus();}
219
220/// Getter for the ABI corpus group being built by the current front-end.
221///
222/// @return the ABI corpus group being built by the current front-end.
223corpus_group_sptr&
225{return priv_->corpus_group;}
226
227/// Getter for the ABI corpus group being built by the current front-end.
228///
229/// @return the ABI corpus group being built by the current front-end.
230const corpus_group_sptr&
232{return const_cast<fe_iface*>(this)->corpus_group();}
233
234/// Setter for the ABI corpus group being built by the current
235/// front-end.
236///
237/// @param cg the new ABI corpus group being built by the current
238/// front-end.
239void
240fe_iface::corpus_group(const ir::corpus_group_sptr& cg)
241{priv_->corpus_group = cg;}
242
243/// Test if there is a corpus group being built.
244///
245/// @return if there is a corpus group being built, false otherwise.
246bool
248{return bool(corpus_group());}
249
250/// Return the main corpus from the current corpus group, if any.
251///
252/// @return the main corpus of the current corpus group, if any, nil
253/// if no corpus group is being constructed.
254corpus_sptr
256{
257 if (corpus_group())
258 return corpus_group()->get_main_corpus();
259 return corpus_sptr();
260}
261
262/// Test if the current corpus being built is the main corpus of the
263/// current corpus group.
264///
265/// @return return true iff the current corpus being built is the
266/// main corpus of the current corpus group.
267bool
269{
270 corpus_sptr main_corpus = main_corpus_from_current_group();
271
272 if (main_corpus.get() == corpus().get())
273 return true;
274
275 return false;
276}
277
278/// Return true if the current corpus is part of a corpus group
279/// being built and if it's not the main corpus of the group.
280///
281/// For instance, this would return true if we are loading a linux
282/// kernel *module* that is part of the current corpus group that is
283/// being built. In this case, it means we should re-use types
284/// coming from the "vmlinux" binary that is the main corpus of the
285/// group.
286///
287/// @return the corpus group the current corpus belongs to, if the
288/// current corpus is part of a corpus group being built. Nil otherwise.
289corpus_sptr
291{
292 if (has_corpus_group())
293 if (corpus_sptr main_corpus = main_corpus_from_current_group())
295 return corpus_group();
296
297 return corpus_sptr();
298}
299
300/// Add the representation of the ABI of a function to the set of
301/// exported declarations or undefined declarations of the current
302/// corpus.
303///
304/// Note that if the function is defined and exported, then it's going
305/// to be added to the set of functions exported by the current
306/// corpus. Otherwise, if the function has an undefined symbol then
307/// it's going to be added to the sef of undefined functions used by
308/// the current corpus.
309///
310/// @param fn the internal representation of the ABI of a function.
311void
313{
314 bool added = false;
315 if (fn)
317 corpus()->get_exported_decls_builder().get())
318 added = b->maybe_add_fn_to_exported_fns(const_cast<function_decl*>(fn));
319
320 if (fn && !added)
321 {
322 if (!fn->get_symbol() || !fn->get_symbol()->is_defined())
323 corpus()->get_undefined_functions().insert(fn);
324 }
325}
326
327/// Add the representation of the ABI of a variable to the set of
328/// exported or undefined declarations of the current corpus.
329///
330/// Note that if the variable is defined and exported, then it's going
331/// to be added to the set of variables exported by the current
332/// corpus. Otherwise, if the variable has an undefined symbol then
333/// it's going to be added to the sef of undefined variables used by
334/// the current corpus.
335///
336/// @param var the internal representation of the ABI of a variable.
337void
339{
340 bool added = false;
341 if (var)
343 corpus()->get_exported_decls_builder().get())
344 added = b->maybe_add_var_to_exported_vars(var);
345
346 if (var && !added)
347 {
348 if (!var->get_symbol() || !var->get_symbol()->is_defined())
349 corpus()->get_undefined_variables().insert(var);
350 }
351}
352
353/// The bitwise OR operator for the @ref fe_iface::status type.
354///
355/// @param l the left-hand side operand.
356///
357/// @param r the right-hand side operand.
358///
359/// @return the result of the operation.
362{
363 return static_cast<fe_iface::status>(static_cast<unsigned>(l)
364 | static_cast<unsigned>(r));
365}
366
367/// The bitwise AND operator for the @ref fe_iface::status type.
368///
369/// @param l the left-hand side operand.
370///
371/// @param r the right-hand side operand.
372///
373/// @return the result of the operation.
376{
377 return static_cast<fe_iface::status>(static_cast<unsigned>(l)
378 & static_cast<unsigned>(r));
379}
380
381/// The bitwise |= operator for the @ref fe_iface::status type.
382///
383/// @param l the left-hand side operand.
384///
385/// @param r the right-hand side operand.
386///
387/// @return the result of the operation.
390{
391 l = l | r;
392 return l;
393}
394
395/// The bitwise &= operator for the @ref fe_iface::status type.
396///
397/// @param l the left-hand side operand.
398///
399/// @param r the right-hand side operand.
400///
401/// @return the result of the operation.
404{
405 l = l & r;
406 return l;
407}
408
409/// Return a diagnostic status with english sentences to describe the
410/// problems encoded in a given abigail::elf_reader::status, if
411/// there is an error.
412///
413/// @param status the status to diagnose
414///
415/// @return a string containing sentences that describe the possible
416/// errors encoded in @p s. If there is no error to encode, then the
417/// empty string is returned.
418std::string
420{
421 std::string str;
422
424 str += "could not find debug info";
425
427 str += "could not find alternate debug info";
428
430 str += "could not load ELF symbols";
431
432 return str;
433}
434
435}// namespace abigail
This file contains the declarations for the fe_iface a.k.a "Front End Interface".
The base class of all libabigail front-ends: The Front End Interface.
Definition: abg-fe-iface.h:29
bool has_corpus_group() const
Test if there is a corpus group being built.
status
The status of the fe_iface::read_corpus call.
Definition: abg-fe-iface.h:38
@ STATUS_NO_SYMBOLS_FOUND
This status is for when the symbols of the ELF binaries could not be read.
Definition: abg-fe-iface.h:54
@ STATUS_DEBUG_INFO_NOT_FOUND
This status is for when the debug info could not be read.
Definition: abg-fe-iface.h:46
@ STATUS_ALT_DEBUG_INFO_NOT_FOUND
This status is for when the alternate debug info could not be found.
Definition: abg-fe-iface.h:50
const options_type & options() const
Getter of the the options of the current Front End Interface.
Definition: abg-fe-iface.cc:92
void add_fn_to_exported_or_undefined_decls(const function_decl *fn)
Add the representation of the ABI of a function to the set of exported declarations or undefined decl...
corpus_sptr corpus()
Getter for the ABI corpus being built by the current front-end.
suppr::suppressions_type & suppressions()
Getter of the vector of suppression specifications associated with the current front-end.
corpus_group_sptr & corpus_group()
Getter for the ABI corpus group being built by the current front-end.
fe_iface(const std::string &corpus_path, environment &e)
Constructor of the type fe_iface.
Definition: abg-fe-iface.cc:68
virtual void initialize(const std::string &corpus_path)
Re-initialize the current Front End.
Definition: abg-fe-iface.cc:82
corpus_sptr should_reuse_type_from_corpus_group()
Return true if the current corpus is part of a corpus group being built and if it's not the main corp...
bool load_in_linux_kernel_mode() const
Test if the input binary is to be considered as a Linux Kernel binary.
bool current_corpus_is_main_corpus_from_current_group()
Test if the current corpus being built is the main corpus of the current corpus group.
virtual ~fe_iface()
Desctructor of the Front End Interface.
Definition: abg-fe-iface.cc:74
void add_var_to_exported_or_undefined_decls(const var_decl *var)
Add the representation of the ABI of a variable to the set of exported or undefined declarations of t...
const std::string & corpus_path() const
Getter of the path to the file which an ABI corpus is to be created for.
const string & dt_soname() const
Getter for the SONAME of the analyzed binary.
corpus_sptr main_corpus_from_current_group()
Return the main corpus from the current corpus group, if any.
void add_suppressions(const suppr::suppressions_type &)
Add suppressions specifications to the set of suppressions to be used during the construction of the ...
Abstracts the building of the set of exported variables and functions.
Definition: abg-corpus.h:334
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition: abg-corpus.h:25
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition: abg-ir.h:140
Abstraction for a function declaration.
Definition: abg-ir.h:3111
const elf_symbol_sptr & get_symbol() const
Gets the the underlying ELF symbol for the current variable, that was set using function_decl::set_sy...
Definition: abg-ir.cc:22102
Abstracts a variable declaration.
Definition: abg-ir.h:3008
const elf_symbol_sptr & get_symbol() const
Gets the the underlying ELF symbol for the current variable, that was set using var_decl::set_symbol(...
Definition: abg-ir.cc:20570
vector< suppression_sptr > suppressions_type
Convenience typedef for a vector of suppression_sptr.
Definition: abg-fwd.h:1658
Toplevel namespace for libabigail.
fe_iface::status & operator|=(fe_iface::status &l, fe_iface::status r)
The bitwise |= operator for the fe_iface::status type.
fe_iface::status & operator&=(fe_iface::status &l, fe_iface::status r)
The bitwise &= operator for the fe_iface::status type.
fe_iface::status operator&(fe_iface::status l, fe_iface::status r)
The bitwise AND operator for the fe_iface::status type.
fe_iface::status operator|(fe_iface::status l, fe_iface::status r)
The bitwise OR operator for the fe_iface::status type.
std::string status_to_diagnostic_string(fe_iface::status s)
Return a diagnostic status with english sentences to describe the problems encoded in a given abigail...
The generic options that control the behaviour of all Front-End interfaces.
Definition: abg-fe-iface.h:60
options_type(environment &)
Constructor of the type fe_iface::options_type.
Definition: abg-fe-iface.cc:57