]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/ia64/dl-machine.h
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / ia64 / dl-machine.h
index 6268fb3e535ea5cf3c63d2743741330ac7d24878..3e934fe30e926a38988780de07871c00b03fbf14 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  IA-64 version.
-   Copyright (C) 1995-1997, 2000-2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1995-2016 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -13,9 +13,8 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #ifndef dl_machine_h
 #define dl_machine_h 1
 #include <string.h>
 #include <link.h>
 #include <errno.h>
+#include <dl-fptr.h>
 #include <tls.h>
 
 /* Translate a processor specific dynamic tag to the index
    in l_info array.  */
 #define DT_IA_64(x) (DT_IA_64_##x - DT_LOPROC + DT_NUM)
 
-/* There are currently 123 dynamic symbols in ld.so.
-   IA64_BOOT_FPTR_TABLE_LEN needs to be at least that big.  */
-#define IA64_BOOT_FPTR_TABLE_LEN       200
-
-/* An FDESC is a function descriptor.  */
-
-struct ia64_fdesc
-  {
-    Elf64_Addr ip;     /* code entry point */
-    Elf64_Addr gp;     /* global pointer */
-  };
-
-struct ia64_fdesc_table
-  {
-    struct ia64_fdesc_table *next;
-    unsigned int len;                  /* # of entries in fdesc table */
-    volatile unsigned int first_unused;        /* index of first available entry */
-    struct ia64_fdesc fdesc[0];
-  };
-
-extern Elf64_Addr __ia64_make_fptr (const struct link_map *,
-                                   const Elf64_Sym *, Elf64_Addr);
-
-static inline void
+static inline void __attribute__ ((always_inline))
 __ia64_init_bootstrap_fdesc_table (struct link_map *map)
 {
   Elf64_Addr *boot_table;
 
   /* careful: this will be called before got has been relocated... */
-  asm (";; addl %0 = @gprel (__ia64_boot_fptr_table), gp" : "=r"(boot_table));
+  asm (";; addl %0 = @gprel (_dl_boot_fptr_table), gp" : "=r"(boot_table));
 
-  map->l_mach.fptr_table_len = IA64_BOOT_FPTR_TABLE_LEN;
+  map->l_mach.fptr_table_len = ELF_MACHINE_BOOT_FPTR_TABLE_LEN;
   map->l_mach.fptr_table = boot_table;
 }
 
@@ -71,7 +48,7 @@ __ia64_init_bootstrap_fdesc_table (struct link_map *map)
        __ia64_init_bootstrap_fdesc_table (&bootstrap_map);
 
 /* Return nonzero iff ELF header is compatible with the running host.  */
-static inline int
+static inline int __attribute__ ((unused))
 elf_machine_matches_host (const Elf64_Ehdr *ehdr)
 {
   return ehdr->e_machine == EM_IA_64;
@@ -79,7 +56,7 @@ elf_machine_matches_host (const Elf64_Ehdr *ehdr)
 
 
 /* Return the link-time address of _DYNAMIC.  */
-static inline Elf64_Addr
+static inline Elf64_Addr __attribute__ ((unused, const))
 elf_machine_dynamic (void)
 {
   Elf64_Addr *p;
@@ -99,7 +76,7 @@ elf_machine_dynamic (void)
 
 
 /* Return the run-time load address of the shared object.  */
-static inline Elf64_Addr
+static inline Elf64_Addr __attribute__ ((unused))
 elf_machine_load_address (void)
 {
   Elf64_Addr ip;
@@ -120,7 +97,7 @@ elf_machine_load_address (void)
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
-static inline int
+static inline int __attribute__ ((unused, always_inline))
 elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 {
   extern void _dl_runtime_resolve (void);
@@ -142,16 +119,17 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 
       /* This function will be called to perform the relocation.  */
       if (!profile)
-       doit = (Elf64_Addr) ((struct ia64_fdesc *) &_dl_runtime_resolve)->ip;
+       doit = (Elf64_Addr) ELF_PTR_TO_FDESC (&_dl_runtime_resolve)->ip;
       else
        {
-         if (_dl_name_match_p (GL(dl_profile), l))
+         if (GLRO(dl_profile) != NULL
+             && _dl_name_match_p (GLRO(dl_profile), l))
            {
              /* This is the object we are looking for.  Say that we really
                 want profiling and the timers are started.  */
              GL(dl_profile_map) = l;
            }
-         doit = (Elf64_Addr) ((struct ia64_fdesc *) &_dl_runtime_profile)->ip;
+         doit = (Elf64_Addr) ELF_PTR_TO_FDESC (&_dl_runtime_profile)->ip;
        }
 
       reserve[1] = doit;
@@ -161,134 +139,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
   return lazy;
 }
 
+/* Names of the architecture-specific auditing callback functions.  */
+#define ARCH_LA_PLTENTER ia64_gnu_pltenter
+#define ARCH_LA_PLTEXIT ia64_gnu_pltexit
 
-/*
-   This code is used in dl-runtime.c to call the `fixup' function
-   and then redirect to the address it returns. `fixup()' takes two
-   arguments, however profile_fixup() takes three.
-
-   The ABI specifies that we will never see more than 8 input
-   registers to a function call, thus it is safe to simply allocate
-   those, and simpler than playing stack games.
-                                                            - 12/09/99 Jes
- */
-#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name)                         \
-  extern void tramp_name (void);                                            \
-  asm (                                                                             \
-"      .global " #tramp_name "#\n"                                          \
-"      .proc " #tramp_name "#\n"                                            \
-#tramp_name ":\n"                                                           \
-"      { .mmi\n"                                                            \
-"        .prologue\n"                                                       \
-"        .save ar.pfs, r40\n"                                               \
-"        alloc loc0 = ar.pfs, 8, 6, 3, 0\n"                                 \
-"        adds r2 = -144, r12\n"                                             \
-"        adds r3 = -128, r12\n"                                             \
-"      }\n"                                                                 \
-"      { .mii\n"                                                            \
-"        .fframe 160\n"                                                     \
-"        adds r12 = -160, r12\n"                                            \
-"        .save rp, r41\n"                                                   \
-"        mov loc1 = b0\n"                                                   \
-"        .body\n"                                                           \
-"        mov out2 = b0         /* needed by fixup_profile */\n"             \
-"        ;;\n"                                                              \
-"      }\n"                                                                 \
-"      { .mfb\n"                                                            \
-"        mov loc2 = r8         /* preserve struct value register */\n"      \
-"        nop.f 0\n"                                                         \
-"        nop.b 0\n"                                                         \
-"      }\n"                                                                 \
-"      { .mii\n"                                                            \
-"        mov loc3 = r9         /* preserve language specific register */\n" \
-"        mov loc4 = r10        /* preserve language specific register */\n" \
-"        mov loc5 = r11        /* preserve language specific register */\n" \
-"      }\n"                                                                 \
-"      { .mmi\n"                                                            \
-"        stf.spill [r2] = f8, 32\n"                                         \
-"        stf.spill [r3] = f9, 32\n"                                         \
-"        mov out0 = r16\n"                                                  \
-"        ;;\n"                                                              \
-"      }\n"                                                                 \
-"      { .mmi\n"                                                            \
-"        stf.spill [r2] = f10, 32\n"                                        \
-"        stf.spill [r3] = f11, 32\n"                                        \
-"        shl out1 = r15, 4\n"                                               \
-"        ;;\n"                                                              \
-"      }\n"                                                                 \
-"      { .mmi\n"                                                            \
-"        stf.spill [r2] = f12, 32\n"                                        \
-"        stf.spill [r3] = f13, 32\n"                                        \
-"        shladd out1 = r15, 3, out1\n"                                      \
-"        ;;\n"                                                              \
-"      }\n"                                                                 \
-"      { .mmb\n"                                                            \
-"        stf.spill [r2] = f14\n"                                            \
-"        stf.spill [r3] = f15\n"                                            \
-"        br.call.sptk.many b0 = " #fixup_name "#\n"                         \
-"      }\n"                                                                 \
-"      { .mii\n"                                                            \
-"        ld8 r9 = [ret0], 8\n"                                              \
-"        adds r2 = 16, r12\n"                                               \
-"        adds r3 = 32, r12\n"                                               \
-"        ;;\n"                                                              \
-"      }\n"                                                                 \
-"      { .mmi\n"                                                            \
-"        ldf.fill f8 = [r2], 32\n"                                          \
-"        ldf.fill f9 = [r3], 32\n"                                          \
-"        mov b0 = loc1\n"                                                   \
-"        ;;\n"                                                              \
-"      }\n"                                                                 \
-"      { .mmi\n"                                                            \
-"        ldf.fill f10 = [r2], 32\n"                                         \
-"        ldf.fill f11 = [r3], 32\n"                                         \
-"        mov b6 = r9\n"                                                     \
-"        ;;\n"                                                              \
-"      }\n"                                                                 \
-"      { .mmi\n"                                                            \
-"        ldf.fill f12 = [r2], 32\n"                                         \
-"        ldf.fill f13 = [r3], 32\n"                                         \
-"        mov ar.pfs = loc0\n"                                               \
-"        ;;\n"                                                              \
-"      }\n"                                                                 \
-"      { .mmi\n"                                                            \
-"        ldf.fill f14 = [r2], 32\n"                                         \
-"        ldf.fill f15 = [r3], 32\n"                                         \
-"        .restore sp           /* pop the unwind frame state */\n"          \
-"        adds r12 = 160, r12\n"                                             \
-"        ;;\n"                                                              \
-"      }\n"                                                                 \
-"      { .mii\n"                                                            \
-"        mov r9 = loc3         /* restore language specific register */\n"  \
-"        mov r10 = loc4        /* restore language specific register */\n"  \
-"        mov r11 = loc5        /* restore language specific register */\n"  \
-"      }\n"                                                                 \
-"      { .mii\n"                                                            \
-"        ld8 gp = [ret0]\n"                                                 \
-"        mov r8 = loc2         /* restore struct value register */\n"       \
-"        ;;\n"                                                              \
-"      }\n"                                                                 \
-"      /* An alloc is needed for the break system call to work.\n"          \
-"         We don't care about the old value of the pfs register.  */\n"     \
-"      { .mmb\n"                                                            \
-"        .prologue\n"                                                       \
-"        .body\n"                                                           \
-"        alloc r2 = ar.pfs, 0, 0, 8, 0\n"                                   \
-"        br.sptk.many b6\n"                                                 \
-"        ;;\n"                                                              \
-"      }\n"                                                                 \
-"      .endp " #tramp_name "#\n");
-
-#ifndef PROF
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE                                 \
-  TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup);            \
-  TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup);
-#else
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE                         \
-  TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup);            \
-  strong_alias (_dl_runtime_resolve, _dl_runtime_profile);
-#endif
-
+/* Undo the adds out0 = 16, sp below to get at the value we want in
+   __libc_stack_end.  */
+#define DL_STACK_END(cookie) \
+  ((void *) (((long) (cookie)) - 16))
 
 /* Initial entry point code for the dynamic linker.
    The C function `_dl_start' is the real entry point;
@@ -301,8 +159,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 "_start:\n"                                                                  \
 "0:    { .mii\n"                                                             \
 "        .prologue\n"                                                        \
-"        .save ar.pfs, r32\n"                                                \
 "        .save rp, r0\n"                                                     \
+"        .body\n"                                                            \
+"        .prologue\n"                                                        \
+"        .save ar.pfs, r32\n"                                                \
 "        alloc loc0 = ar.pfs, 0, 3, 4, 0\n"                                  \
 "        .body\n"                                                            \
 "        mov r2 = ip\n"                                                      \
@@ -332,25 +192,20 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 "      .proc _dl_start_user#\n"                                              \
 "_dl_start_user:\n"                                                          \
 "       .prologue\n"                                                         \
-"       .save ar.pfs, r32\n"                                                 \
 "       .save rp, r0\n"                                                      \
+"        .body\n"                                                            \
+"       .prologue\n"                                                         \
+"       .save ar.pfs, r32\n"                                                 \
 "       .body\n"                                                             \
 "      { .mii\n"                                                             \
-"        /* Save the pointer to the user entry point fptr in loc2.  */\n"    \
-"        mov loc2 = ret0\n"                                                  \
-"        /* Store the highest stack address.  */\n"                          \
-"        addl r2 = @ltoff(__libc_stack_end#), gp\n"                          \
 "        addl r3 = @gprel(_dl_skip_args), gp\n"                              \
-"        ;;\n"                                                               \
-"      }\n"                                                                  \
-"      { .mmi\n"                                                             \
-"        ld8 r2 = [r2]\n"                                                    \
-"        ld4 r3 = [r3]\n"                                                    \
 "        adds r11 = 24, sp     /* Load the address of argv. */\n"            \
+"        /* Save the pointer to the user entry point fptr in loc2.  */\n"    \
+"        mov loc2 = ret0\n"                                                  \
 "        ;;\n"                                                               \
 "      }\n"                                                                  \
 "      { .mii\n"                                                             \
-"        st8 [r2] = sp\n"                                                    \
+"        ld4 r3 = [r3]\n"                                                    \
 "        adds r10 = 16, sp     /* Load the address of argc. */\n"            \
 "        mov out2 = r11\n"                                                   \
 "        ;;\n"                                                               \
@@ -416,10 +271,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 "      }\n"                                                                  \
 "      { .mmb\n"                                                             \
 "        st8 [r2] = r17                /* Load the new _dl_argv. */\n"       \
-"        br.call.sptk.many b0 = _dl_init_internal#\n"                        \
+"        br.call.sptk.many b0 = _dl_init#\n"                                 \
 "        ;;\n"                                                               \
 "      }\n"                                                                  \
-"      /* Pass our finializer function to the user,\n"                       \
+"      /* Pass our finalizer function to the user,\n"                        \
 "         and jump to the user's entry point.  */\n"                         \
 "      { .mmi\n"                                                             \
 "        ld8 r3 = [loc2], 8\n"                                               \
@@ -451,58 +306,53 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or TLS
    variable, so undefined references should not be allowed to define the
    value.
-   ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+   ELF_RTYPE_CLASS_COPY iff TYPE should not be allowed to resolve to one
    of the main executable's symbols, as for a COPY reloc, which we don't
    use.  */
 /* ??? Ignore *MSB for now.  */
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
 #define elf_machine_type_class(type) \
   (((type) == R_IA64_IPLTLSB || (type) == R_IA64_DTPMOD64LSB                 \
     || (type) == R_IA64_DTPREL64LSB || (type) == R_IA64_TPREL64LSB)          \
    * ELF_RTYPE_CLASS_PLT)
-#else
-#define elf_machine_type_class(type) \
-  (((type) == R_IA64_IPLTLSB) * ELF_RTYPE_CLASS_PLT)
-#endif
 
 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
 #define ELF_MACHINE_JMP_SLOT    R_IA64_IPLTLSB
 
 /* According to the IA-64 specific documentation, Rela is always used.  */
 #define ELF_MACHINE_NO_REL 1
+#define ELF_MACHINE_NO_RELA 0
 
 /* Return the address of the entry point. */
-#define ELF_MACHINE_START_ADDRESS(map, start)  \
-  DL_STATIC_FUNCTION_ADDRESS (map, start)
-
-#define elf_machine_profile_fixup_plt(l, reloc, rel_addr, value) \
-  elf_machine_fixup_plt (l, reloc, rel_addr, value)
-
-#define elf_machine_profile_plt(reloc_addr) ((Elf64_Addr) (reloc_addr))
+#define ELF_MACHINE_START_ADDRESS(map, start)                  \
+({                                                             \
+       ElfW(Addr) addr;                                        \
+       DL_DT_FUNCTION_ADDRESS(map, start, static, addr)        \
+       addr;                                                   \
+})
 
 /* Fixup a PLT entry to bounce directly to the function at VALUE.  */
-static inline Elf64_Addr
+static inline struct fdesc __attribute__ ((always_inline))
 elf_machine_fixup_plt (struct link_map *l, lookup_t t,
                       const Elf64_Rela *reloc,
-                      Elf64_Addr *reloc_addr, Elf64_Addr value)
+                      Elf64_Addr *reloc_addr, struct fdesc value)
 {
   /* l is the link_map for the caller, t is the link_map for the object
    * being called */
   /* got has already been relocated in elf_get_dynamic_info() */
-  reloc_addr[1] = t->l_info[DT_PLTGOT]->d_un.d_ptr;
+  reloc_addr[1] = value.gp;
   /* we need a "release" here to ensure that the gp is visible before
      the code entry point is updated: */
-  ((volatile Elf64_Addr *) reloc_addr)[0] = value;
-  return (Elf64_Addr) reloc_addr;
+  ((volatile Elf64_Addr *) reloc_addr)[0] = value.ip;
+  return value;
 }
 
 /* Return the final value of a plt relocation.  */
-static inline Elf64_Addr
+static inline struct fdesc
 elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
-                      Elf64_Addr value)
+                      struct fdesc value)
 {
   /* No need to handle rel vs rela since IA64 is rela only */
-  return value + reloc->r_addend;
+  return (struct fdesc) { value.ip + reloc->r_addend, value.gp };
 }
 
 #endif /* !dl_machine_h */
@@ -520,13 +370,16 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
 
 /* Perform the relocation specified by RELOC and SYM (which is fully
    resolved).  MAP is the object containing the reloc.  */
-static inline void
+auto inline void
+__attribute ((always_inline))
 elf_machine_rela (struct link_map *map,
                  const Elf64_Rela *reloc,
                  const Elf64_Sym *sym,
                  const struct r_found_version *version,
-                 Elf64_Addr *const reloc_addr)
+                 void *const reloc_addr_arg,
+                 int skip_ifunc)
 {
+  Elf64_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
   Elf64_Addr value;
 
@@ -552,7 +405,7 @@ elf_machine_rela (struct link_map *map,
       /* Already done in dynamic linker.  */
       if (map != &GL(dl_rtld_map))
 # endif
-        value += map->l_addr;
+       value += map->l_addr;
     }
   else
 #endif
@@ -564,42 +417,41 @@ elf_machine_rela (struct link_map *map,
 
       /* RESOLVE_MAP() will return NULL if it fail to locate the symbol.  */
       if ((sym_map = RESOLVE_MAP (&sym, version, r_type)))
-        {
+       {
          value = sym_map->l_addr + sym->st_value + reloc->r_addend;
 
          if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DIR64LSB))
            ;/* No adjustment.  */
          else if (r_type == R_IA64_IPLTLSB)
            {
-             elf_machine_fixup_plt (NULL, sym_map, reloc, reloc_addr, value);
+             elf_machine_fixup_plt (NULL, NULL, reloc, reloc_addr,
+                                    DL_FIXUP_MAKE_VALUE (sym_map, value));
              return;
            }
          else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_FPTR64LSB))
-           value = __ia64_make_fptr (sym_map, sym, value);
+           value = _dl_make_fptr (sym_map, sym, value);
          else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_PCREL64LSB))
            value -= (Elf64_Addr) reloc_addr & -16;
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || defined USE___THREAD)
          else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DTPMOD64LSB))
-# ifdef RTLD_BOOTSTRAP
+#ifdef RTLD_BOOTSTRAP
            /* During startup the dynamic linker is always index 1.  */
            value = 1;
-# else
+#else
            /* Get the information from the link map returned by the
               resolv function.  */
            value = sym_map->l_tls_modid;
          else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DTPREL64LSB))
            value -= sym_map->l_addr;
-# endif
+#endif
          else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_TPREL64LSB))
            {
-# ifndef RTLD_BOOTSTRAP
+#ifndef RTLD_BOOTSTRAP
              CHECK_STATIC_TLS (map, sym_map);
-# endif
+#endif
              value += sym_map->l_tls_offset - sym_map->l_addr;
            }
-#endif
          else
-           assert (! "unexpected dynamic reloc type");
+           _dl_reloc_bad_type (map, r_type, 0);
        }
       else
        value = 0;
@@ -616,17 +468,19 @@ elf_machine_rela (struct link_map *map,
       reloc_addr[1] = 0;
     }
   else
-    assert (! "unexpected dynamic reloc format");
+    _dl_reloc_bad_type (map, r_type, 0);
 }
 
 /* Let do-rel.h know that on IA-64 if l_addr is 0, all RELATIVE relocs
    can be skipped.  */
 #define ELF_MACHINE_REL_RELATIVE 1
 
-static inline void
+auto inline void
+__attribute ((always_inline))
 elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
-                          Elf64_Addr *const reloc_addr)
+                          void *const reloc_addr_arg)
 {
+  Elf64_Addr *const reloc_addr = reloc_addr_arg;
   /* ??? Ignore MSB and Instruction format for now.  */
   assert (ELF64_R_TYPE (reloc->r_info) == R_IA64_REL64LSB);
 
@@ -634,9 +488,11 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 }
 
 /* Perform a RELATIVE reloc on the .got entry that transfers to the .plt.  */
-static inline void
+auto inline void
+__attribute ((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-                     Elf64_Addr l_addr, const Elf64_Rela *reloc)
+                     Elf64_Addr l_addr, const Elf64_Rela *reloc,
+                     int skip_ifunc)
 {
   Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
@@ -649,7 +505,7 @@ elf_machine_lazy_rel (struct link_map *map,
   else if (r_type == R_IA64_NONE)
     return;
   else
-    assert (! "unexpected PLT reloc type");
+    _dl_reloc_bad_type (map, r_type, 1);
 }
 
 #endif /* RESOLVE_MAP */