+
+2019-03-27  Ali Tamur  <tamur@google.com>
+
+       * dwarf2-frame.c(dwarf_expr_executor::get_addr_index): Update comment
+       * dwarf2expr.c(dwarf_expr_context::execute_stack_op): Add DW_OP_addrx
+       * dwarf2expr.h(dwarf_expr_context::offset): Update comment
+       (dwarf_expr_context::get_addr_index): Likewise
+       * dwarf2loc.c(dwarf_evaluate_loc_desc::get_addr_index): Likewise
+       (symbol_needs_eval_context::get_addr_index): Likewise
+       (disassemble_dwarf_expression): Add DW_OP_addrx
+       * dwarf2read.c(attr_value_as_address): Add DW_FORM_addrx
+       (read_cutu_die_from_dwo): Update comment
+       (skip_one_die): Add DW_FORM_addrx
+       (read_attribute_value): Likewise
+       (var_decode_location): Add DW_OP_addrx
+       (dwarf2_const_value_attr): Add DW_FORM_addrx
+       (dump_die_shallow): Likewise
+       (dwarf2_fetch_constant_bytes): Likewise
+       (decode_locdesc): Add DW_OP_addrx
+       (skip_form_bytes): Add DW_FORM_addrx
+
 2019-04-22  Ali Tamur  <tamur@google.com>
 
        * MAINTAINERS (Write After Approval): Add self.
 
 
   CORE_ADDR get_addr_index (unsigned int index) override
   {
-    invalid ("DW_OP_GNU_addr_index");
+    invalid ("DW_OP_addrx or DW_OP_GNU_addr_index");
   }
 
  private:
 
          result_val = value_from_ulongest (address_type, result);
          break;
 
+       case DW_OP_addrx:
        case DW_OP_GNU_addr_index:
          op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
          result = this->get_addr_index (uoffset);
 
      context and operations depending on DW_FORM_ref_addr are not allowed.  */
   int ref_addr_size;
 
-  /* Offset used to relocate DW_OP_addr and DW_OP_GNU_addr_index arguments.  */
+  /* Offset used to relocate DW_OP_addr, DW_OP_addrx, and
+     DW_OP_GNU_addr_index arguments.  */
   CORE_ADDR offset;
 
   /* The current depth of dwarf expression recursion, via DW_OP_call*,
                                           union call_site_parameter_u kind_u,
                                           int deref_size) = 0;
 
-  /* Return the address indexed by DW_OP_GNU_addr_index.
+  /* Return the address indexed by DW_OP_addrx or DW_OP_GNU_addr_index.
      This can throw an exception if the index is out of range.  */
   virtual CORE_ADDR get_addr_index (unsigned int index) = 0;
 
 
   }
 
   /* Callback function for dwarf2_evaluate_loc_desc.
-     Fetch the address indexed by DW_OP_GNU_addr_index.  */
+     Fetch the address indexed by DW_OP_addrx or DW_OP_GNU_addr_index.  */
 
   CORE_ADDR get_addr_index (unsigned int index) override
   {
     push_address (0, 0);
   }
 
-  /* DW_OP_GNU_addr_index doesn't require a frame.  */
+  /* DW_OP_addrx and DW_OP_GNU_addr_index doesn't require a frame.  */
 
    CORE_ADDR get_addr_index (unsigned int index) override
    {
          fprintf_filtered (stream, " offset %s", phex_nz (ul, 4));
          break;
 
+       case DW_OP_addrx:
        case DW_OP_GNU_addr_index:
          data = safe_read_uleb128 (data, end, &ul);
          ul = dwarf2_read_addr_index (per_cu, ul);
 
 {
   CORE_ADDR addr;
 
-  if (attr->form != DW_FORM_addr && attr->form != DW_FORM_GNU_addr_index)
+  if (attr->form != DW_FORM_addr && attr->form != DW_FORM_addrx
+      && attr->form != DW_FORM_GNU_addr_index)
     {
       /* Aside from a few clearly defined exceptions, attributes that
         contain an address must always be in DW_FORM_addr form.
       comp_dir = dwarf2_attr (stub_comp_unit_die, DW_AT_comp_dir, cu);
 
       /* There should be a DW_AT_addr_base attribute here (if needed).
-        We need the value before we can process DW_FORM_GNU_addr_index.  */
+        We need the value before we can process DW_FORM_GNU_addr_index
+         or DW_FORM_addrx.  */
       cu->addr_base = 0;
       attr = dwarf2_attr (stub_comp_unit_die, DW_AT_GNU_addr_base, cu);
       if (attr)
        case DW_FORM_block4:
          info_ptr += 4 + read_4_bytes (abfd, info_ptr);
          break;
+       case DW_FORM_addrx:
        case DW_FORM_sdata:
        case DW_FORM_udata:
        case DW_FORM_ref_udata:
     case DW_FORM_implicit_const:
       DW_SND (attr) = implicit_const;
       break;
+    case DW_FORM_addrx:
     case DW_FORM_GNU_addr_index:
       if (reader->dwo_file == NULL)
        {
 
   /* Handle one degenerate form of location expression specially, to
      preserve GDB's previous behavior when section offsets are
-     specified.  If this is just a DW_OP_addr or DW_OP_GNU_addr_index
-     then mark this symbol as LOC_STATIC.  */
+     specified.  If this is just a DW_OP_addr, DW_OP_addrx, or
+     DW_OP_GNU_addr_index then mark this symbol as LOC_STATIC.  */
 
   if (attr_form_is_block (attr)
       && ((DW_BLOCK (attr)->data[0] == DW_OP_addr
           && DW_BLOCK (attr)->size == 1 + cu_header->addr_size)
-         || (DW_BLOCK (attr)->data[0] == DW_OP_GNU_addr_index
+         || ((DW_BLOCK (attr)->data[0] == DW_OP_GNU_addr_index
+               || DW_BLOCK (attr)->data[0] == DW_OP_addrx)
              && (DW_BLOCK (attr)->size
                  == 1 + leb128_size (&DW_BLOCK (attr)->data[1])))))
     {
   switch (attr->form)
     {
     case DW_FORM_addr:
+    case DW_FORM_addrx:
     case DW_FORM_GNU_addr_index:
       {
        gdb_byte *data;
       switch (die->attrs[i].form)
        {
        case DW_FORM_addr:
+       case DW_FORM_addrx:
        case DW_FORM_GNU_addr_index:
          fprintf_unfiltered (f, "address: ");
          fputs_filtered (hex_string (DW_ADDR (&die->attrs[i])), f);
   switch (attr->form)
     {
     case DW_FORM_addr:
+    case DW_FORM_addrx:
     case DW_FORM_GNU_addr_index:
       {
        gdb_byte *tem;
        case DW_OP_GNU_uninit:
          break;
 
+       case DW_OP_addrx:
        case DW_OP_GNU_addr_index:
        case DW_OP_GNU_const_index:
          stack[++stacki] = read_addr_index_from_leb128 (cu, &data[i],
       bytes += 4 + read_4_bytes (abfd, bytes);
       break;
 
+    case DW_FORM_addrx:
     case DW_FORM_sdata:
     case DW_FORM_udata:
     case DW_FORM_GNU_addr_index: