proc-events.c: fix compilation on Solaris
[deliverable/binutils-gdb.git] / gdb / linespec.c
index 8951c1e8c4736026f247dd85120bf4d8b037fe14..194d50cb3a19432f94b9f569612bd3d7a89adf82 100644 (file)
@@ -2258,12 +2258,6 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
   else if (ls->function_symbols != NULL || ls->minimal_symbols != NULL)
     {
       /* We have just a bunch of functions and/or methods.  */
-      int i;
-      struct symtab_and_line sal;
-      struct symbol *sym;
-      bound_minimal_symbol_d *elem;
-      struct program_space *pspace;
-
       if (ls->function_symbols != NULL)
        {
          /* Sort symbols so that symbols with the same program space are next
@@ -2272,30 +2266,81 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
                 VEC_length (symbolp, ls->function_symbols),
                 sizeof (symbolp), compare_symbols);
 
-         for (i = 0; VEC_iterate (symbolp, ls->function_symbols, i, sym); ++i)
+         struct symbol *sym;
+         for (int i = 0; VEC_iterate (symbolp, ls->function_symbols, i, sym); ++i)
            {
-             pspace = SYMTAB_PSPACE (symbol_symtab (sym));
+             program_space *pspace = SYMTAB_PSPACE (symbol_symtab (sym));
              set_current_program_space (pspace);
-             if (symbol_to_sal (&sal, state->funfirstline, sym)
-                 && maybe_add_address (state->addr_set, pspace, sal.pc))
-               add_sal_to_sals (state, &sals, &sal,
-                                SYMBOL_NATURAL_NAME (sym), 0);
+
+             /* Don't skip to the first line of the function if we
+                had found an ifunc minimal symbol for this function,
+                because that means that this function is an ifunc
+                resolver with the same name as the ifunc itself.  */
+             bool found_ifunc = false;
+
+             if (state->funfirstline
+                  && ls->minimal_symbols != NULL
+                  && SYMBOL_CLASS (sym) == LOC_BLOCK)
+               {
+                 const CORE_ADDR addr
+                   = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+
+                 bound_minimal_symbol_d *elem;
+                 for (int m = 0;
+                      VEC_iterate (bound_minimal_symbol_d, ls->minimal_symbols,
+                                   m, elem);
+                      ++m)
+                   {
+                     if (MSYMBOL_TYPE (elem->minsym) == mst_text_gnu_ifunc
+                         || MSYMBOL_TYPE (elem->minsym) == mst_data_gnu_ifunc)
+                       {
+                         CORE_ADDR msym_addr = BMSYMBOL_VALUE_ADDRESS (*elem);
+                         if (MSYMBOL_TYPE (elem->minsym) == mst_data_gnu_ifunc)
+                           {
+                             struct gdbarch *gdbarch
+                               = get_objfile_arch (elem->objfile);
+                             msym_addr
+                               = (gdbarch_convert_from_func_ptr_addr
+                                  (gdbarch,
+                                   msym_addr,
+                                   &current_target));
+                           }
+
+                         if (msym_addr == addr)
+                           {
+                             found_ifunc = true;
+                             break;
+                           }
+                       }
+                   }
+               }
+
+             if (!found_ifunc)
+               {
+                 symtab_and_line sal;
+                 if (symbol_to_sal (&sal, state->funfirstline, sym)
+                     && maybe_add_address (state->addr_set, pspace, sal.pc))
+                   add_sal_to_sals (state, &sals, &sal,
+                                    SYMBOL_NATURAL_NAME (sym), 0);
+               }
            }
        }
 
       if (ls->minimal_symbols != NULL)
        {
-         /* Sort minimal symbols by program space, too.  */
+         /* Sort minimal symbols by program space, too  */
          qsort (VEC_address (bound_minimal_symbol_d, ls->minimal_symbols),
                 VEC_length (bound_minimal_symbol_d, ls->minimal_symbols),
                 sizeof (bound_minimal_symbol_d), compare_msymbols);
 
-         for (i = 0;
+         bound_minimal_symbol_d *elem;
+
+         for (int i = 0;
               VEC_iterate (bound_minimal_symbol_d, ls->minimal_symbols,
                            i, elem);
               ++i)
            {
-             pspace = elem->objfile->pspace;
+             program_space *pspace = elem->objfile->pspace;
              set_current_program_space (pspace);
              minsym_found (state, elem->objfile, elem->minsym, &sals);
            }
@@ -4244,33 +4289,36 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
              struct minimal_symbol *msymbol,
              std::vector<symtab_and_line> *result)
 {
-  struct symtab_and_line sal;
+  bool want_start_sal;
 
   CORE_ADDR func_addr;
-  if (msymbol_is_function (objfile, msymbol, &func_addr))
-    {
-      sal = find_pc_sect_line (func_addr, NULL, 0);
+  bool is_function = msymbol_is_function (objfile, msymbol, &func_addr);
 
-      if (self->funfirstline)
-       {
-         if (sal.symtab != NULL
-             && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab))
-                 || SYMTAB_LANGUAGE (sal.symtab) == language_asm))
-           {
-             struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  if (is_function)
+    {
+      const char *msym_name = MSYMBOL_LINKAGE_NAME (msymbol);
 
-             sal.pc = func_addr;
-             if (gdbarch_skip_entrypoint_p (gdbarch))
-               sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc);
-           }
-         else
-           skip_prologue_sal (&sal);
-       }
+      if (MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc
+         || MSYMBOL_TYPE (msymbol) == mst_data_gnu_ifunc)
+       want_start_sal = gnu_ifunc_resolve_name (msym_name, &func_addr);
+      else
+       want_start_sal = true;
     }
+
+  symtab_and_line sal;
+
+  if (is_function && want_start_sal)
+    sal = find_function_start_sal (func_addr, NULL, self->funfirstline);
   else
     {
       sal.objfile = objfile;
-      sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
+      sal.msymbol = msymbol;
+      /* Store func_addr, not the minsym's address in case this was an
+        ifunc that hasn't been resolved yet.  */
+      if (is_function)
+       sal.pc = func_addr;
+      else
+       sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
       sal.pspace = current_program_space;
     }
 
This page took 0.040869 seconds and 4 git commands to generate.