diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 7fca76b..a592b66 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -2442,28 +2442,15 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 	case DWARF_VALUE_LITERAL:
 	  {
 	    bfd_byte *contents;
-	    const bfd_byte *ldata;
-	    size_t n = ctx.len;
+	    size_t n = TYPE_LENGTH (type);
 
-	    if (byte_offset + TYPE_LENGTH (type) > n)
+	    if (byte_offset + n > ctx.len)
 	      invalid_synthetic_pointer ();
 
 	    free_values.free_to_mark ();
 	    retval = allocate_value (type);
 	    contents = value_contents_raw (retval);
-
-	    ldata = ctx.data + byte_offset;
-	    n -= byte_offset;
-
-	    if (n > TYPE_LENGTH (type))
-	      {
-		struct gdbarch *objfile_gdbarch = get_objfile_arch (objfile);
-
-		if (gdbarch_byte_order (objfile_gdbarch) == BFD_ENDIAN_BIG)
-		  ldata += n - TYPE_LENGTH (type);
-		n = TYPE_LENGTH (type);
-	      }
-	    memcpy (contents, ldata, n);
+	    memcpy (contents, ctx.data + byte_offset, n);
 	  }
 	  break;
 
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-op-stack-value.exp b/gdb/testsuite/gdb.dwarf2/dw2-op-stack-value.exp
index c28dcca..808f983 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-op-stack-value.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-op-stack-value.exp
@@ -45,7 +45,7 @@ gdb_test_multiple $test $test {
     -re ":\[ \t\]*0xaa551234\r\n$gdb_prompt $" {
 	# big endian
 	pass $test
-	gdb_test "p/x implicit4to2" " = 0x3344"
+	gdb_test "p/x implicit4to2" " = 0x1122"
 	gdb_test "p/x implicit4to4" " = 0x11223344"
     }
     -re ":\[ \t\]*0x\[0-9a-f\]{8}\r\n$gdb_prompt $" {
diff --git a/gdb/testsuite/gdb.dwarf2/nonvar-access.exp b/gdb/testsuite/gdb.dwarf2/nonvar-access.exp
index 506ff9e..f47df70 100644
--- a/gdb/testsuite/gdb.dwarf2/nonvar-access.exp
+++ b/gdb/testsuite/gdb.dwarf2/nonvar-access.exp
@@ -31,14 +31,23 @@ Dwarf::assemble $asm_file {
 	compile_unit {
 	    {DW_AT_name main.c}
 	} {
-	    declare_labels int_type_label short_type_label
-	    declare_labels struct_s_label struct_t_label
+	    declare_labels int_type_label char_type_label \
+		struct_s_label struct_t_label array_a9_label \
+		char_ptr_label implicit_a_label
 
 	    int_type_label: base_type {
 		{name "int"}
 		{encoding @DW_ATE_signed}
 		{byte_size 4 DW_FORM_sdata}
 	    }
+	    char_type_label: base_type {
+		{name "char"}
+		{encoding @DW_ATE_unsigned}
+		{byte_size 1 DW_FORM_sdata}
+	    }
+	    char_ptr_label: pointer_type {
+		{type :$char_type_label}
+	    }
 
 	    struct_s_label: structure_type {
 		{name s}
@@ -76,20 +85,32 @@ Dwarf::assemble $asm_file {
 		}
 	    }
 
+	    array_a9_label: array_type {
+		{type :$char_type_label}
+	    } {
+		subrange_type {
+		    {type :$int_type_label}
+		    {upper_bound 8 DW_FORM_udata}
+		}
+	    }
+
 	    DW_TAG_subprogram {
 		{name main}
 		{DW_AT_external 1 flag}
 		{low_pc [gdb_target_symbol main] DW_FORM_addr}
 		{high_pc [gdb_target_symbol main]+0x10000 DW_FORM_addr}
 	    } {
+		# Simple variable without location.
 		DW_TAG_variable {
 		    {name undef_int}
 		    {type :$int_type_label}
 		}
+		# Struct variable without location.
 		DW_TAG_variable {
 		    {name undef_s}
 		    {type :$struct_s_label}
 		}
+		# Composite location: byte-aligned pieces.
 		DW_TAG_variable {
 		    {name def_s}
 		    {type :$struct_s_label}
@@ -102,6 +123,7 @@ Dwarf::assemble $asm_file {
 			bit_piece 24 0
 		    } SPECIAL_expr}
 		}
+		# Composite location: non-byte-aligned pieces.
 		DW_TAG_variable {
 		    {name def_t}
 		    {type :$struct_t_label}
@@ -114,6 +136,32 @@ Dwarf::assemble $asm_file {
 			bit_piece 23 0
 		    } SPECIAL_expr}
 		}
+		# Implicit location: immediate value.
+		DW_TAG_variable {
+		    {name def_implicit_s}
+		    {type :$struct_s_label}
+		    {location {
+			implicit_value 0x12 0x34 0x56 0x78
+		    } SPECIAL_expr}
+		}
+		# Implicit location: immediate value for whole array, with
+		# excess bytes.
+		implicit_a_label: DW_TAG_variable {
+		    {name def_implicit_a}
+		    {type :$array_a9_label}
+		    {location {
+			implicit_value 0x01 0x12 0x23 0x34 0x45 \
+			    0x56 0x67 0x78 0x89 0x9a 0xab
+		    } SPECIAL_expr}
+		}
+		# Implicit pointer into immediate value.
+		DW_TAG_variable {
+		    {name implicit_a_ptr}
+		    {type :$char_ptr_label}
+		    {location {
+			GNU_implicit_pointer $implicit_a_label 5
+		    } SPECIAL_expr}
+		}
 	    }
 	}
     }
@@ -128,7 +176,33 @@ if ![runto_main] {
     return -1
 }
 
+# Determine endianness.
+set endian "little"
+gdb_test_multiple "show endian" "determine endianness" {
+    -re ".* (big|little) endian.*$gdb_prompt $" {
+	set endian $expect_out(1,string)
+	pass "endianness: $endian"
+    }
+}
+
+# Byte-aligned objects with simple location descriptions.
+switch $endian { big {set val 0x345678} little {set val 0x785634} }
+gdb_test "print/x def_implicit_s" " = \\{a = 0x12, b = $val\\}"
+gdb_test "print/x def_implicit_s.b" " = $val"
+gdb_test "print/x def_implicit_a" \
+    " = \\{0x1, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89\\}"
+gdb_test "print/x def_implicit_a\[5\]" " = 0x56"
+gdb_test "print/x *(char (*)\[5\]) implicit_a_ptr" \
+    " = \\{0x56, 0x67, 0x78, 0x89, 0x9a\\}"
+
+# Byte-aligned fields, pieced together from DWARF stack values.
 gdb_test "print def_s" " = \\{a = 0, b = -1\\}"
+
+# Non-byte-aligned fields, pieced together from DWARF stack values.
 gdb_test "print def_t" " = \\{a = 0, b = -1\\}"
+
+# Simple variable without location.
 gdb_test "print undef_int" " = <optimized out>"
+
+# Member of a structure without location.
 gdb_test "print undef_s.a" " = <optimized out>"
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index 9f5fa6c..6bd563a 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -906,6 +906,25 @@ namespace eval Dwarf {
 		    _op .2byte [lindex $line 1]
 		}
 
+		DW_OP_implicit_value {
+		    set l1 [new_label "value_start"]
+		    set l2 [new_label "value_end"]
+		    _op .uleb128 "$l2 - $l1"
+		    define_label $l1
+		    foreach value [lrange $line 1 end] {
+			switch -regexp -- $value {
+			    {^0x[[:xdigit:]]{2}$} {_op .byte $value}
+			    {^0x[[:xdigit:]]{4}$} {_op .2byte $value}
+			    {^0x[[:xdigit:]]{8}$} {_op .4byte $value}
+			    {^0x[[:xdigit:]]{16}$} {_op .8byte $value}
+			    default {
+				error "bad value '$value' in DW_OP_implicit_value"
+			    }
+			}
+		    }
+		    define_label $l2
+		}
+
 		DW_OP_GNU_implicit_pointer {
 		    if {[llength $line] != 3} {
 			error "usage: DW_OP_GNU_implicit_pointer LABEL OFFSET"
