@@ -861,84 +861,159 @@ ResolveLoadAddress(ExecutionContext *exe_ctx, lldb::ModuleSP &module_sp,
861861 return load_addr;
862862}
863863
864- static llvm::Error Evaluate_DW_OP_deref (DWARFExpression::Stack &stack,
865- ExecutionContext *exe_ctx,
866- lldb::ModuleSP module_sp,
867- Process *process) {
868- if (stack.empty ())
869- return llvm::createStringError (" expression stack empty for DW_OP_deref" );
870-
871- const Value::ValueType value_type = stack.back ().GetValueType ();
864+ // / Helper function to move common code used to load sized data from a uint8_t
865+ // / buffer.
866+ // /
867+ // / \param addr_bytes uint8_t buffer containg raw data
868+ // / \param size_addr_bytes how large is the underlying raw data
869+ // / \param byte_order what is the byter order of the underlyig data
870+ // / \param size How much of the underlying data we want to use
871+ // / \return The underlying data converted into a Scalar
872+ static Scalar DerefSizeExtractDataHelper (uint8_t *addr_bytes,
873+ size_t size_addr_bytes,
874+ ByteOrder byte_order, size_t size) {
875+ DataExtractor addr_data (addr_bytes, size_addr_bytes, byte_order, size);
876+
877+ lldb::offset_t addr_data_offset = 0 ;
878+ if (size <= 8 )
879+ return addr_data.GetMaxU64 (&addr_data_offset, size);
880+ else
881+ return addr_data.GetAddress (&addr_data_offset);
882+ }
883+
884+ static llvm::Error Evaluate_DW_OP_deref_size (DWARFExpression::Stack &stack,
885+ ExecutionContext *exe_ctx,
886+ lldb::ModuleSP module_sp,
887+ Process *process, Target *target,
888+ uint8_t size) {
889+ if (stack.empty ()) {
890+ return llvm::createStringError (
891+ " expression stack empty for DW_OP_deref_size" );
892+ }
893+
894+ if (size > 8 ) {
895+ return llvm::createStringError (
896+ " Invalid address size for DW_OP_deref_size: %d\n " , size);
897+ }
898+ Value::ValueType value_type = stack.back ().GetValueType ();
872899 switch (value_type) {
873900 case Value::ValueType::HostAddress: {
874901 void *src = (void *)stack.back ().GetScalar ().ULongLong ();
875902 intptr_t ptr;
876903 ::memcpy (&ptr, src, sizeof (void *));
904+ // I can't decide whether the size operand should apply to the bytes in
905+ // their
906+ // lldb-host endianness or the target endianness.. I doubt this'll ever
907+ // come up but I'll opt for assuming big endian regardless.
908+ switch (size) {
909+ case 1 :
910+ ptr = ptr & 0xff ;
911+ break ;
912+ case 2 :
913+ ptr = ptr & 0xffff ;
914+ break ;
915+ case 3 :
916+ ptr = ptr & 0xffffff ;
917+ break ;
918+ case 4 :
919+ ptr = ptr & 0xffffffff ;
920+ break ;
921+ // the casts are added to work around the case where intptr_t is a 32
922+ // bit quantity;
923+ // presumably we won't hit the 5..7 cases if (void*) is 32-bits in this
924+ // program.
925+ case 5 :
926+ ptr = (intptr_t )ptr & 0xffffffffffULL ;
927+ break ;
928+ case 6 :
929+ ptr = (intptr_t )ptr & 0xffffffffffffULL ;
930+ break ;
931+ case 7 :
932+ ptr = (intptr_t )ptr & 0xffffffffffffffULL ;
933+ break ;
934+ default :
935+ break ;
936+ }
877937 stack.back ().GetScalar () = ptr;
878938 stack.back ().ClearContext ();
879939 } break ;
880940 case Value::ValueType::FileAddress: {
881941 auto file_addr = stack.back ().GetScalar ().ULongLong (LLDB_INVALID_ADDRESS);
882942 Address so_addr;
883- auto maybe_load_addr = ResolveLoadAddress (exe_ctx, module_sp, " DW_OP_deref" ,
884- file_addr, so_addr);
943+ auto maybe_load_addr = ResolveLoadAddress (
944+ exe_ctx, module_sp, " DW_OP_deref_size" , file_addr, so_addr,
945+ /* check_sectionoffset=*/ true );
946+
885947 if (!maybe_load_addr)
886948 return maybe_load_addr.takeError ();
887- stack.back ().GetScalar () = *maybe_load_addr;
949+
950+ addr_t load_addr = *maybe_load_addr;
951+
952+ if (load_addr == LLDB_INVALID_ADDRESS && so_addr.IsSectionOffset ()) {
953+ uint8_t addr_bytes[8 ];
954+ Status error;
955+
956+ if (target && target->ReadMemory (so_addr, &addr_bytes, size, error,
957+ /* force_live_memory=*/ false ) == size) {
958+ ObjectFile *objfile = module_sp->GetObjectFile ();
959+
960+ stack.back ().GetScalar () = DerefSizeExtractDataHelper (
961+ addr_bytes, size, objfile->GetByteOrder (), size);
962+ stack.back ().ClearContext ();
963+ break ;
964+ } else {
965+ return llvm::createStringError (
966+ " Failed to dereference pointer for DW_OP_deref_size: "
967+ " %s\n " ,
968+ error.AsCString ());
969+ }
970+ }
971+ stack.back ().GetScalar () = load_addr;
888972 // Fall through to load address promotion code below.
889973 }
974+
890975 [[fallthrough]];
891976 case Value::ValueType::Scalar:
892977 // Promote Scalar to LoadAddress and fall through.
893978 stack.back ().SetValueType (Value::ValueType::LoadAddress);
894979 [[fallthrough]];
895- case Value::ValueType::LoadAddress: {
896- if (!exe_ctx)
897- return llvm::createStringError (" NULL execution context for DW_OP_deref" );
898- if (!process)
899- return llvm::createStringError (" NULL process for DW_OP_deref" );
900- lldb::addr_t pointer_addr =
901- stack.back ().GetScalar ().ULongLong (LLDB_INVALID_ADDRESS);
902- Status error;
903- lldb::addr_t pointer_value =
904- process->ReadPointerFromMemory (pointer_addr, error);
905- if (pointer_value == LLDB_INVALID_ADDRESS)
906- return llvm::joinErrors (
907- llvm::createStringError (
980+ case Value::ValueType::LoadAddress:
981+ if (exe_ctx) {
982+ if (process) {
983+ lldb::addr_t pointer_addr =
984+ stack.back ().GetScalar ().ULongLong (LLDB_INVALID_ADDRESS);
985+ uint8_t addr_bytes[sizeof (lldb::addr_t )];
986+ Status error;
987+ if (process->ReadMemory (pointer_addr, &addr_bytes, size, error) ==
988+ size) {
989+
990+ stack.back ().GetScalar () = DerefSizeExtractDataHelper (
991+ addr_bytes, sizeof (addr_bytes), process->GetByteOrder (), size);
992+ stack.back ().ClearContext ();
993+ } else {
994+ return llvm::createStringError (
908995 " Failed to dereference pointer from 0x%" PRIx64
909- " for DW_OP_deref" ,
910- pointer_addr),
911- error.takeError ());
912- stack.back ().GetScalar () = pointer_value;
913- stack.back ().ClearContext ();
914- } break ;
996+ " for DW_OP_deref: %s\n " ,
997+ pointer_addr, error.AsCString ());
998+ }
999+ } else {
1000+
1001+ return llvm::createStringError (" NULL process for DW_OP_deref_size" );
1002+ }
1003+ } else {
1004+ return llvm::createStringError (
1005+ " NULL execution context for DW_OP_deref_size" );
1006+ }
1007+ break ;
1008+
9151009 case Value::ValueType::Invalid:
916- return llvm::createStringError (" invalid value type for DW_OP_deref" );
1010+
1011+ return llvm::createStringError (" invalid value for DW_OP_deref_size" );
9171012 }
9181013
9191014 return llvm::Error::success ();
9201015}
9211016
922- // / Helper function to move common code used to load sized data from a uint8_t
923- // / buffer.
924- // /
925- // / \param addr_bytes uint8_t buffer containg raw data
926- // / \param size_addr_bytes how large is the underlying raw data
927- // / \param byte_order what is the byter order of the underlyig data
928- // / \param size How much of the underlying data we want to use
929- // / \return The underlying data converted into a Scalar
930- static Scalar DerefSizeExtractDataHelper (uint8_t *addr_bytes,
931- size_t size_addr_bytes,
932- ByteOrder byte_order, size_t size) {
933- DataExtractor addr_data (addr_bytes, size_addr_bytes, byte_order, size);
934-
935- lldb::offset_t addr_data_offset = 0 ;
936- if (size <= 8 )
937- return addr_data.GetMaxU64 (&addr_data_offset, size);
938- else
939- return addr_data.GetAddress (&addr_data_offset);
940- }
941-
9421017llvm::Expected<Value> DWARFExpression::Evaluate (
9431018 ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
9441019 lldb::ModuleSP module_sp, const DataExtractor &opcodes,
@@ -1079,8 +1154,9 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
10791154 // retrieved from the dereferenced address is the size of an address on the
10801155 // target machine.
10811156 case DW_OP_deref: {
1082- if (llvm::Error err =
1083- Evaluate_DW_OP_deref (stack, exe_ctx, module_sp, process))
1157+ size_t size = opcodes.GetAddressByteSize ();
1158+ if (llvm::Error err = Evaluate_DW_OP_deref_size (stack, exe_ctx, module_sp,
1159+ process, target, size))
10841160 return err;
10851161 } break ;
10861162
@@ -1097,131 +1173,10 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
10971173 // the size of an address on the target machine before being pushed on the
10981174 // expression stack.
10991175 case DW_OP_deref_size: {
1100- if (stack.empty ()) {
1101- return llvm::createStringError (
1102- " expression stack empty for DW_OP_deref_size" );
1103- }
1104- uint8_t size = opcodes.GetU8 (&offset);
1105- if (size > 8 ) {
1106- return llvm::createStringError (
1107- " Invalid address size for DW_OP_deref_size: %d\n " , size);
1108- }
1109- Value::ValueType value_type = stack.back ().GetValueType ();
1110- switch (value_type) {
1111- case Value::ValueType::HostAddress: {
1112- void *src = (void *)stack.back ().GetScalar ().ULongLong ();
1113- intptr_t ptr;
1114- ::memcpy (&ptr, src, sizeof (void *));
1115- // I can't decide whether the size operand should apply to the bytes in
1116- // their
1117- // lldb-host endianness or the target endianness.. I doubt this'll ever
1118- // come up but I'll opt for assuming big endian regardless.
1119- switch (size) {
1120- case 1 :
1121- ptr = ptr & 0xff ;
1122- break ;
1123- case 2 :
1124- ptr = ptr & 0xffff ;
1125- break ;
1126- case 3 :
1127- ptr = ptr & 0xffffff ;
1128- break ;
1129- case 4 :
1130- ptr = ptr & 0xffffffff ;
1131- break ;
1132- // the casts are added to work around the case where intptr_t is a 32
1133- // bit quantity;
1134- // presumably we won't hit the 5..7 cases if (void*) is 32-bits in this
1135- // program.
1136- case 5 :
1137- ptr = (intptr_t )ptr & 0xffffffffffULL ;
1138- break ;
1139- case 6 :
1140- ptr = (intptr_t )ptr & 0xffffffffffffULL ;
1141- break ;
1142- case 7 :
1143- ptr = (intptr_t )ptr & 0xffffffffffffffULL ;
1144- break ;
1145- default :
1146- break ;
1147- }
1148- stack.back ().GetScalar () = ptr;
1149- stack.back ().ClearContext ();
1150- } break ;
1151- case Value::ValueType::FileAddress: {
1152- auto file_addr =
1153- stack.back ().GetScalar ().ULongLong (LLDB_INVALID_ADDRESS);
1154- Address so_addr;
1155- auto maybe_load_addr = ResolveLoadAddress (
1156- exe_ctx, module_sp, " DW_OP_deref_size" , file_addr, so_addr,
1157- /* check_sectionoffset=*/ true );
1158-
1159- if (!maybe_load_addr)
1160- return maybe_load_addr.takeError ();
1161-
1162- addr_t load_addr = *maybe_load_addr;
1163-
1164- if (load_addr == LLDB_INVALID_ADDRESS && so_addr.IsSectionOffset ()) {
1165- uint8_t addr_bytes[8 ];
1166- Status error;
1167-
1168- if (target &&
1169- target->ReadMemory (so_addr, &addr_bytes, size, error,
1170- /* force_live_memory=*/ false ) == size) {
1171- ObjectFile *objfile = module_sp->GetObjectFile ();
1172-
1173- stack.back ().GetScalar () = DerefSizeExtractDataHelper (
1174- addr_bytes, size, objfile->GetByteOrder (), size);
1175- stack.back ().ClearContext ();
1176- break ;
1177- } else {
1178- return llvm::createStringError (
1179- " Failed to dereference pointer for DW_OP_deref_size: "
1180- " %s\n " ,
1181- error.AsCString ());
1182- }
1183- }
1184- stack.back ().GetScalar () = load_addr;
1185- // Fall through to load address promotion code below.
1186- }
1187-
1188- [[fallthrough]];
1189- case Value::ValueType::Scalar:
1190- case Value::ValueType::LoadAddress:
1191- if (exe_ctx) {
1192- if (process) {
1193- lldb::addr_t pointer_addr =
1194- stack.back ().GetScalar ().ULongLong (LLDB_INVALID_ADDRESS);
1195- uint8_t addr_bytes[sizeof (lldb::addr_t )];
1196- Status error;
1197- if (process->ReadMemory (pointer_addr, &addr_bytes, size, error) ==
1198- size) {
1199-
1200- stack.back ().GetScalar () =
1201- DerefSizeExtractDataHelper (addr_bytes, sizeof (addr_bytes),
1202- process->GetByteOrder (), size);
1203- stack.back ().ClearContext ();
1204- } else {
1205- return llvm::createStringError (
1206- " Failed to dereference pointer from 0x%" PRIx64
1207- " for DW_OP_deref: %s\n " ,
1208- pointer_addr, error.AsCString ());
1209- }
1210- } else {
1211-
1212- return llvm::createStringError (" NULL process for DW_OP_deref_size" );
1213- }
1214- } else {
1215- return llvm::createStringError (
1216- " NULL execution context for DW_OP_deref_size" );
1217- }
1218- break ;
1219-
1220- case Value::ValueType::Invalid:
1221-
1222- return llvm::createStringError (" invalid value for DW_OP_deref_size" );
1223- }
1224-
1176+ size_t size = opcodes.GetU8 (&offset);
1177+ if (llvm::Error err = Evaluate_DW_OP_deref_size (stack, exe_ctx, module_sp,
1178+ process, target, size))
1179+ return err;
12251180 } break ;
12261181
12271182 // OPCODE: DW_OP_xderef_size
0 commit comments