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