Home | History | Annotate | Line # | Download | only in arch
amd64-linux-tdesc.c revision 1.1
      1  1.1  christos /* Target description related code for GNU/Linux x86-64.
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2024 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of GDB.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19  1.1  christos 
     20  1.1  christos #include "arch/x86-linux-tdesc.h"
     21  1.1  christos #include "arch/amd64-linux-tdesc.h"
     22  1.1  christos #include "arch/amd64.h"
     23  1.1  christos #include "arch/x86-linux-tdesc-features.h"
     24  1.1  christos 
     25  1.1  christos 
     26  1.1  christos /* See arch/amd64-linux-tdesc.h.  */
     27  1.1  christos 
     28  1.1  christos const struct target_desc *
     29  1.1  christos amd64_linux_read_description (uint64_t xcr0, bool is_x32)
     30  1.1  christos {
     31  1.1  christos   /* The type used for the amd64 and x32 target description caches.  */
     32  1.1  christos   using tdesc_cache_type = std::unordered_map<uint64_t, const target_desc_up>;
     33  1.1  christos 
     34  1.1  christos   /* Caches for the previously seen amd64 and x32 target descriptions,
     35  1.1  christos      indexed by the xcr0 value that created the target description.  These
     36  1.1  christos      need to be static within this function to ensure they are initialised
     37  1.1  christos      before first use.  */
     38  1.1  christos   static tdesc_cache_type amd64_tdesc_cache, x32_tdesc_cache;
     39  1.1  christos 
     40  1.1  christos   tdesc_cache_type &tdesc_cache = is_x32 ? x32_tdesc_cache : amd64_tdesc_cache;
     41  1.1  christos 
     42  1.1  christos   /* Only some bits are checked when creating a tdesc, but the XCR0 value
     43  1.1  christos      contains other feature bits that are not relevant for tdesc creation.
     44  1.1  christos      When indexing into the TDESC_CACHE we need to use a consistent xcr0
     45  1.1  christos      value otherwise we might fail to find an existing tdesc which has the
     46  1.1  christos      same set of relevant bits set.  */
     47  1.1  christos   xcr0 &= is_x32
     48  1.1  christos     ? x86_linux_x32_xcr0_feature_mask ()
     49  1.1  christos     : x86_linux_amd64_xcr0_feature_mask ();
     50  1.1  christos 
     51  1.1  christos   const auto it = tdesc_cache.find (xcr0);
     52  1.1  christos   if (it != tdesc_cache.end ())
     53  1.1  christos     return it->second.get ();
     54  1.1  christos 
     55  1.1  christos   /* Create the previously unseen target description.  */
     56  1.1  christos   target_desc_up tdesc (amd64_create_target_description (xcr0, is_x32,
     57  1.1  christos 							 true, true));
     58  1.1  christos   x86_linux_post_init_tdesc (tdesc.get (), true);
     59  1.1  christos 
     60  1.1  christos   /* Add to the cache, and return a pointer borrowed from the
     61  1.1  christos      target_desc_up.  This is safe as the cache (and the pointers contained
     62  1.1  christos      within it) are not deleted until GDB exits.  */
     63  1.1  christos   target_desc *ptr = tdesc.get ();
     64  1.1  christos   tdesc_cache.emplace (xcr0, std::move (tdesc));
     65  1.1  christos   return ptr;
     66  1.1  christos }
     67