+2020-05-27  Simon Marchi  <simon.marchi@efficios.com>
+
+       * dwarf2/expr.h (struct dwarf_expr_context)
+       <dwarf_expr_context>: Add dwarf2_per_objfile parameter.
+       <offset>: Remove.
+       <per_objfile>: New member.
+       * dwarf2/expr.c (dwarf_expr_context::dwarf_expr_context): Add
+       dwarf2_per_objfile parameter.  Don't set offset, set
+       per_objfile.
+       (dwarf_expr_context::execute_stack_op): Use offset from objfile.
+       * dwarf2/frame.c (dwarf2_frame_find_fde): Return (by parameter)
+       a dwarf2_per_objfile object instead of an offset.
+       (class dwarf_expr_executor) <dwarf_expr_executor>: Add
+       constructor.
+       (execute_stack_op): Add dwarf2_per_objfile parameter, pass it
+       to dwarf2_expr_executor constructor.  Don't set offset.
+       (dwarf2_fetch_cfa_info): Update.
+       (struct dwarf2_frame_cache) <text_offset>: Remove.
+       <per_objfile>: New field.
+       (dwarf2_frame_cache): Update.
+       (dwarf2_frame_prev_register): Update.
+       * dwarf2/loc.c (class dwarf_evaluate_loc_desc)
+       <dwarf_evaluate_loc_desc>: Add constructor.
+       (dwarf2_evaluate_loc_desc_full): Update.
+       (dwarf2_locexpr_baton_eval): Update.
+       (class symbol_needs_eval_context) <symbol_needs_eval_context>:
+       Add constructor.
+       (dwarf2_loc_desc_get_symbol_read_needs): Update.
+
 2020-05-27  Simon Marchi  <simon.marchi@efficios.com>
 
        * dwarf2/read.h (struct dwarf2_per_cu_data) <addr_type,
 
   auto_obstack obstack;
 };
 
-static struct dwarf2_fde *dwarf2_frame_find_fde (CORE_ADDR *pc,
-                                                CORE_ADDR *out_offset);
+static struct dwarf2_fde *dwarf2_frame_find_fde
+  (CORE_ADDR *pc, dwarf2_per_objfile **out_per_objfile);
 
 static int dwarf2_frame_adjust_regnum (struct gdbarch *gdbarch, int regnum,
                                       int eh_frame_p);
 
 class dwarf_expr_executor : public dwarf_expr_context
 {
- public:
+public:
+
+  dwarf_expr_executor (dwarf2_per_objfile *per_objfile)
+    : dwarf_expr_context (per_objfile)
+  {}
 
   struct frame_info *this_frame;
 
 
 static CORE_ADDR
 execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
-                 CORE_ADDR offset, struct frame_info *this_frame,
-                 CORE_ADDR initial, int initial_in_stack_memory)
+                 struct frame_info *this_frame, CORE_ADDR initial,
+                 int initial_in_stack_memory, dwarf2_per_objfile *per_objfile)
 {
   CORE_ADDR result;
 
-  dwarf_expr_executor ctx;
+  dwarf_expr_executor ctx (per_objfile);
   scoped_value_mark free_values;
 
   ctx.this_frame = this_frame;
   ctx.gdbarch = get_frame_arch (this_frame);
   ctx.addr_size = addr_size;
   ctx.ref_addr_size = -1;
-  ctx.offset = offset;
 
   ctx.push_address (initial, initial_in_stack_memory);
   ctx.eval (exp, len);
                       const gdb_byte **cfa_end_out)
 {
   struct dwarf2_fde *fde;
-  CORE_ADDR text_offset;
+  dwarf2_per_objfile *per_objfile;
   CORE_ADDR pc1 = pc;
 
   /* Find the correct FDE.  */
-  fde = dwarf2_frame_find_fde (&pc1, &text_offset);
+  fde = dwarf2_frame_find_fde (&pc1, &per_objfile);
   if (fde == NULL)
     error (_("Could not compute CFA; needed to translate this expression"));
 
+  gdb_assert (per_objfile != nullptr);
+
   dwarf2_frame_state fs (pc1, fde->cie);
 
   /* Check for "quirks" - known bugs in producers.  */
 
   /* First decode all the insns in the CIE.  */
   execute_cfa_program (fde, fde->cie->initial_instructions,
-                      fde->cie->end, gdbarch, pc, &fs, text_offset);
+                      fde->cie->end, gdbarch, pc, &fs,
+                      per_objfile->objfile->text_section_offset ());
 
   /* Save the initialized register set.  */
   fs.initial = fs.regs;
 
   /* Then decode the insns in the FDE up to our target PC.  */
   execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, pc, &fs,
-                      text_offset);
+                      per_objfile->objfile->text_section_offset ());
 
   /* Calculate the CFA.  */
   switch (fs.regs.cfa_how)
       }
 
     case CFA_EXP:
-      *text_offset_out = text_offset;
+      *text_offset_out = per_objfile->objfile->text_section_offset ();
       *cfa_start_out = fs.regs.cfa_exp;
       *cfa_end_out = fs.regs.cfa_exp + fs.regs.cfa_exp_len;
       return 0;
   /* Target address size in bytes.  */
   int addr_size;
 
-  /* The .text offset.  */
-  CORE_ADDR text_offset;
+  /* The dwarf2_per_objfile from which this frame description came.  */
+  dwarf2_per_objfile *per_objfile;
 
   /* If not NULL then this frame is the bottom frame of a TAILCALL_FRAME
      sequence.  If NULL then it is a normal case with no TAILCALL_FRAME
   CORE_ADDR pc1 = get_frame_address_in_block (this_frame);
 
   /* Find the correct FDE.  */
-  fde = dwarf2_frame_find_fde (&pc1, &cache->text_offset);
+  fde = dwarf2_frame_find_fde (&pc1, &cache->per_objfile);
   gdb_assert (fde != NULL);
+  gdb_assert (cache->per_objfile != nullptr);
 
   /* Allocate and initialize the frame state.  */
   struct dwarf2_frame_state fs (pc1, fde->cie);
   execute_cfa_program (fde, fde->cie->initial_instructions,
                       fde->cie->end, gdbarch,
                       get_frame_address_in_block (this_frame), &fs,
-                      cache->text_offset);
+                      cache->per_objfile->objfile->text_section_offset ());
 
   /* Save the initialized register set.  */
   fs.initial = fs.regs;
       && entry_pc < fde->initial_location + fde->address_range)
     {
       /* Decode the insns in the FDE up to the entry PC.  */
-      instr = execute_cfa_program (fde, fde->instructions, fde->end, gdbarch,
-                                  entry_pc, &fs, cache->text_offset);
+      instr = execute_cfa_program
+       (fde, fde->instructions, fde->end, gdbarch, entry_pc, &fs,
+        cache->per_objfile->objfile->text_section_offset ());
 
       if (fs.regs.cfa_how == CFA_REG_OFFSET
          && (dwarf_reg_to_regnum (gdbarch, fs.regs.cfa_reg)
   /* Then decode the insns in the FDE up to our target PC.  */
   execute_cfa_program (fde, instr, fde->end, gdbarch,
                       get_frame_address_in_block (this_frame), &fs,
-                      cache->text_offset);
+                      cache->per_objfile->objfile->text_section_offset ());
 
   try
     {
        case CFA_EXP:
          cache->cfa =
            execute_stack_op (fs.regs.cfa_exp, fs.regs.cfa_exp_len,
-                             cache->addr_size, cache->text_offset,
-                             this_frame, 0, 0);
+                             cache->addr_size, this_frame, 0, 0,
+                             cache->per_objfile);
          break;
 
        default:
     case DWARF2_FRAME_REG_SAVED_EXP:
       addr = execute_stack_op (cache->reg[regnum].loc.exp.start,
                               cache->reg[regnum].loc.exp.len,
-                              cache->addr_size, cache->text_offset,
-                              this_frame, cache->cfa, 1);
+                              cache->addr_size,
+                              this_frame, cache->cfa, 1,
+                              cache->per_objfile);
       return frame_unwind_got_memory (this_frame, regnum, addr);
 
     case DWARF2_FRAME_REG_SAVED_VAL_OFFSET:
     case DWARF2_FRAME_REG_SAVED_VAL_EXP:
       addr = execute_stack_op (cache->reg[regnum].loc.exp.start,
                               cache->reg[regnum].loc.exp.len,
-                              cache->addr_size, cache->text_offset,
-                              this_frame, cache->cfa, 1);
+                              cache->addr_size,
+                              this_frame, cache->cfa, 1,
+                              cache->per_objfile);
       return frame_unwind_got_constant (this_frame, regnum, addr);
 
     case DWARF2_FRAME_REG_UNSPECIFIED:
    initial location associated with it into *PC.  */
 
 static struct dwarf2_fde *
-dwarf2_frame_find_fde (CORE_ADDR *pc, CORE_ADDR *out_offset)
+dwarf2_frame_find_fde (CORE_ADDR *pc, dwarf2_per_objfile **out_per_objfile)
 {
   for (objfile *objfile : current_program_space->objfiles ())
     {
       if (it != fde_table->end ())
         {
           *pc = (*it)->initial_location + offset;
-         if (out_offset)
-           *out_offset = offset;
+         if (out_per_objfile != nullptr)
+           *out_per_objfile = get_dwarf2_per_objfile (objfile);
+
           return *it;
         }
     }
 
 
 class dwarf_evaluate_loc_desc : public dwarf_expr_context
 {
- public:
+public:
+  dwarf_evaluate_loc_desc (dwarf2_per_objfile *per_objfile)
+    : dwarf_expr_context (per_objfile)
+  {}
 
   struct frame_info *frame;
   struct dwarf2_per_cu_data *per_cu;
     this->gdbarch = per_cu->objfile ()->arch ();
     scoped_restore save_addr_size = make_scoped_restore (&this->addr_size);
     this->addr_size = per_cu->addr_size ();
-    scoped_restore save_offset = make_scoped_restore (&this->offset);
-    this->offset = per_cu->text_offset ();
 
     this->eval (data_src, size);
   }
   if (size == 0)
     return allocate_optimized_out_value (subobj_type);
 
-  dwarf_evaluate_loc_desc ctx;
+  dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+  dwarf_evaluate_loc_desc ctx (per_objfile);
   ctx.frame = frame;
   ctx.per_cu = per_cu;
   ctx.obj_address = 0;
   ctx.gdbarch = objfile->arch ();
   ctx.addr_size = per_cu->addr_size ();
   ctx.ref_addr_size = per_cu->ref_addr_size ();
-  ctx.offset = per_cu->text_offset ();
 
   try
     {
 
 struct evaluate_for_locexpr_baton : public dwarf_evaluate_loc_desc
 {
+  evaluate_for_locexpr_baton (dwarf2_per_objfile *per_objfile)
+    : dwarf_evaluate_loc_desc (per_objfile)
+  {}
+
   /* The data that was passed in.  */
   gdb::array_view<const gdb_byte> data_view;
 
                           CORE_ADDR *valp,
                           bool push_initial_value)
 {
-  struct objfile *objfile;
-
   if (dlbaton == NULL || dlbaton->size == 0)
     return 0;
 
-  evaluate_for_locexpr_baton ctx;
+  dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
+  evaluate_for_locexpr_baton ctx (per_objfile);
 
   ctx.frame = frame;
   ctx.per_cu = dlbaton->per_cu;
       ctx.data_view = addr_stack->valaddr;
     }
 
-  objfile = dlbaton->per_objfile->objfile;
-
-  ctx.gdbarch = objfile->arch ();
+  ctx.gdbarch = per_objfile->objfile->arch ();
   ctx.addr_size = dlbaton->per_cu->addr_size ();
   ctx.ref_addr_size = dlbaton->per_cu->ref_addr_size ();
-  ctx.offset = dlbaton->per_cu->text_offset ();
 
   if (push_initial_value)
     ctx.push_address (ctx.obj_address, false);
 
 class symbol_needs_eval_context : public dwarf_expr_context
 {
- public:
+public:
+  symbol_needs_eval_context (dwarf2_per_objfile *per_objfile)
+    : dwarf_expr_context (per_objfile)
+  {}
 
   enum symbol_needs_kind needs;
   struct dwarf2_per_cu_data *per_cu;
 
   scoped_value_mark free_values;
 
-  symbol_needs_eval_context ctx;
+  symbol_needs_eval_context ctx (get_dwarf2_per_objfile (objfile));
 
   ctx.needs = SYMBOL_NEEDS_NONE;
   ctx.per_cu = per_cu;
   ctx.gdbarch = objfile->arch ();
   ctx.addr_size = per_cu->addr_size ();
   ctx.ref_addr_size = per_cu->ref_addr_size ();
-  ctx.offset = per_cu->text_offset ();
 
   ctx.eval (data, size);