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-2025 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.reset();
50 }
51}; //end struct fe_iface::priv
52
53/// Constructor of the type @ref fe_iface::options_type.
54///
55/// @param e the environment used by the Front End Interface.
57 : env(e)
58{
59}
60
61/// Constructor of the type @ref fe_iface.
62///
63/// @param corpus_path the path to the file represented by the ABI
64/// corpus that is going to be built by this Front End.
65///
66/// @param e the environment in which the Front End operates.
68 : priv_(new priv(corpus_path, e))
69{
70}
71
72/// Desctructor of the Front End Interface.
74{delete priv_;}
75
76/// Re-initialize the current Front End.
77///
78/// @param corpus_path the path to the file for which a new corpus is
79/// to be created.
80void
81fe_iface::initialize(const std::string& corpus_path)
82{
83 priv_->initialize();
84 priv_->corpus_path = corpus_path;
85}
86
87/// Getter of the the options of the current Front End Interface.
88///
89/// @return the options of the current Front End Interface.
92{return priv_->options;}
93
94/// Getter of the the options of the current Front End Interface.
95///
96/// @return the options of the current Front End Interface.
99{return priv_->options;}
100
101/// Getter of the path to the file which an ABI corpus is to be
102/// created for.
103///
104/// @return the path to the file which an ABI corpus is to be created
105/// for.
106const std::string&
108{return priv_->corpus_path;}
109
110/// Setter of the path to the file which an ABI corpus is to be
111/// created for.
112///
113/// @param p the new path to the file which an ABI corpus is to be
114/// created for.
115void
116fe_iface::corpus_path(const std::string& p)
117{priv_->corpus_path = p;}
118
119/// Getter for the SONAME of the analyzed binary.
120///
121/// @return the SONAME of the analyzed binary.
122const string&
124{return priv_->dt_soname;}
125
126/// Getter for the SONAME of the analyzed binary.
127///
128/// @return the SONAME of the analyzed binary.
129void
130fe_iface::dt_soname(const string& soname)
131{priv_->dt_soname = soname;}
132
133/// Test if the input binary is to be considered as a Linux Kernel
134/// binary.
135///
136/// @return true iff the input binary is to be considered as a Linux
137/// Kernel binary.
138bool
140{return priv_->options.load_in_linux_kernel_mode;}
141
142/// Getter of the vector of suppression specifications associated with
143/// the current front-end.
144///
145/// @return the vector of suppression specifications associated with
146/// the current front-end.
149{return priv_->suppressions;}
150
151/// Getter of the vector of suppression specifications associated with
152/// the current front-end.
153///
154/// @return the vector of suppression specifications associated with
155/// the current front-end.
158{return priv_->suppressions;}
159
160/// Setter of the vector of suppression specifications associated with
161/// the current front-end.
162///
163/// @param supprs the new vector of suppression specifications
164/// associated with the current front-end.
165void
167{priv_->suppressions = supprs;}
168
169/// Add suppressions specifications to the set of suppressions to be
170/// used during the construction of the ABI internal representation
171/// (the ABI corpus) from the input file.
172///
173/// During the construction of the ABI corpus, ABI artifacts that
174/// match a given suppression specification are dropped on the floor;
175/// that is, they are discarded and won't be part of the final ABI
176/// corpus. This is a way to reduce the amount of data held by the
177/// final ABI corpus.
178///
179/// Note that the suppression specifications provided to this function
180/// are only considered during the construction of the ABI corpus.
181/// For instance, they are not taken into account during e.g
182/// comparisons of two ABI corpora that might happen later. If you
183/// want to apply suppression specificatins to the comparison (or
184/// reporting) of ABI corpora please refer to the documentation of the
185/// @ref diff_context type to learn how to set suppressions that are
186/// to be used in that context.
187///
188/// @param supprs the suppression specifications to be applied during
189/// the construction of the ABI corpus.
190void
192{
193 for (const auto& s : supprs)
194 if (s->get_drops_artifact_from_ir())
195 suppressions().push_back(s);
196}
197
198/// Getter for the ABI corpus being built by the current front-end.
199///
200/// @return the ABI corpus being built by the current front-end.
201corpus_sptr
203{
204 if (!priv_->corpus)
205 {
206 priv_->corpus = std::make_shared<ir::corpus>(options().env,
207 corpus_path());
208 }
209 return priv_->corpus;
210}
211
212/// Getter for the ABI corpus being built by the current front-end.
213///
214/// @return the ABI corpus being built by the current front-end.
215const corpus_sptr
217{return const_cast<fe_iface*>(this)->corpus();}
218
219/// Getter for the ABI corpus group being built by the current front-end.
220///
221/// @return the ABI corpus group being built by the current front-end.
222corpus_group_sptr&
224{return priv_->corpus_group;}
225
226/// Getter for the ABI corpus group being built by the current front-end.
227///
228/// @return the ABI corpus group being built by the current front-end.
229const corpus_group_sptr&
231{return const_cast<fe_iface*>(this)->corpus_group();}
232
233/// Setter for the ABI corpus group being built by the current
234/// front-end.
235///
236/// @param cg the new ABI corpus group being built by the current
237/// front-end.
238void
239fe_iface::corpus_group(const ir::corpus_group_sptr& cg)
240{priv_->corpus_group = cg;}
241
242/// Test if there is a corpus group being built.
243///
244/// @return if there is a corpus group being built, false otherwise.
245bool
247{return bool(corpus_group());}
248
249/// Return the main corpus from the current corpus group, if any.
250///
251/// @return the main corpus of the current corpus group, if any, nil
252/// if no corpus group is being constructed.
253corpus_sptr
255{
256 if (corpus_group())
257 return corpus_group()->get_main_corpus();
258 return corpus_sptr();
259}
260
261/// Test if the current corpus being built is the main corpus of the
262/// current corpus group.
263///
264/// @return return true iff the current corpus being built is the
265/// main corpus of the current corpus group.
266bool
268{
269 corpus_sptr main_corpus = main_corpus_from_current_group();
270
271 if (main_corpus.get() == corpus().get())
272 return true;
273
274 return false;
275}
276
277/// Return true if the current corpus is part of a corpus group
278/// being built and if it's not the main corpus of the group.
279///
280/// For instance, this would return true if we are loading a linux
281/// kernel *module* that is part of the current corpus group that is
282/// being built. In this case, it means we should re-use types
283/// coming from the "vmlinux" binary that is the main corpus of the
284/// group.
285///
286/// @return the corpus group the current corpus belongs to, if the
287/// current corpus is part of a corpus group being built. Nil otherwise.
288corpus_sptr
290{
291 if (has_corpus_group())
292 if (corpus_sptr main_corpus = main_corpus_from_current_group())
294 return corpus_group();
295
296 return corpus_sptr();
297}
298
299/// Add the representation of the ABI of a function to the set of
300/// exported declarations or undefined declarations of the current
301/// corpus.
302///
303/// Note that if the function is defined and exported, then it's going
304/// to be added to the set of functions exported by the current
305/// corpus. Otherwise, if the function has an undefined symbol then
306/// it's going to be added to the sef of undefined functions used by
307/// the current corpus.
308///
309/// @param fn the internal representation of the ABI of a function.
310void
312{
313 bool added = false;
314 if (fn)
316 corpus()->get_exported_decls_builder().get())
317 added = b->maybe_add_fn_to_exported_fns(const_cast<function_decl*>(fn));
318
319 if (fn && !added)
320 {
321 if (!fn->get_symbol() || !fn->get_symbol()->is_defined())
322 corpus()->get_undefined_functions().insert(fn);
323 }
324}
325
326/// Add the representation of the ABI of a variable to the set of
327/// exported or undefined declarations of the current corpus.
328///
329/// Note that if the variable is defined and exported, then it's going
330/// to be added to the set of variables exported by the current
331/// corpus. Otherwise, if the variable has an undefined symbol then
332/// it's going to be added to the sef of undefined variables used by
333/// the current corpus.
334///
335/// @param var the internal representation of the ABI of a variable.
336void
338{
339 bool added = false;
340 if (var)
342 corpus()->get_exported_decls_builder().get())
343 added = b->maybe_add_var_to_exported_vars(var);
344
345 if (var && !added)
346 {
347 if (!var->get_symbol() || !var->get_symbol()->is_defined())
348 corpus()->get_undefined_variables().insert(var);
349 }
350}
351
352/// The bitwise OR operator for the @ref fe_iface::status type.
353///
354/// @param l the left-hand side operand.
355///
356/// @param r the right-hand side operand.
357///
358/// @return the result of the operation.
361{
362 return static_cast<fe_iface::status>(static_cast<unsigned>(l)
363 | static_cast<unsigned>(r));
364}
365
366/// The bitwise AND operator for the @ref fe_iface::status type.
367///
368/// @param l the left-hand side operand.
369///
370/// @param r the right-hand side operand.
371///
372/// @return the result of the operation.
375{
376 return static_cast<fe_iface::status>(static_cast<unsigned>(l)
377 & static_cast<unsigned>(r));
378}
379
380/// The bitwise |= operator for the @ref fe_iface::status type.
381///
382/// @param l the left-hand side operand.
383///
384/// @param r the right-hand side operand.
385///
386/// @return the result of the operation.
389{
390 l = l | r;
391 return l;
392}
393
394/// The bitwise &= operator for the @ref fe_iface::status type.
395///
396/// @param l the left-hand side operand.
397///
398/// @param r the right-hand side operand.
399///
400/// @return the result of the operation.
403{
404 l = l & r;
405 return l;
406}
407
408/// Return a diagnostic status with english sentences to describe the
409/// problems encoded in a given abigail::elf_reader::status, if
410/// there is an error.
411///
412/// @param status the status to diagnose
413///
414/// @return a string containing sentences that describe the possible
415/// errors encoded in @p s. If there is no error to encode, then the
416/// empty string is returned.
417std::string
419{
420 std::string str;
421
423 str += "could not find debug info";
424
426 str += "could not find alternate debug info";
427
429 str += "could not load ELF symbols";
430
431 return str;
432}
433
434}// 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:91
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:67
virtual void initialize(const std::string &corpus_path)
Re-initialize the current Front End.
Definition: abg-fe-iface.cc:81
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.
void add_var_to_exported_or_undefined_decls(const var_decl_sptr &var)
Add the representation of the ABI of a variable to the set of exported or undefined declarations of t...
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:73
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:337
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:148
Abstraction for a function declaration.
Definition: abg-ir.h:3165
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:22945
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition: abg-fwd.h:256
vector< suppression_sptr > suppressions_type
Convenience typedef for a vector of suppression_sptr.
Definition: abg-fwd.h:1681
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:56