From 3f451b21ece5c35b28e4221647bf5c486e69badc Mon Sep 17 00:00:00 2001 From: maxim Date: Mon, 10 Dec 2018 22:31:03 +0000 Subject: [PATCH] Merged revision(s) 59776 #7e6959a326 from trunk: FpDebug: Fix Dwarf3 on 64bit. The The 32/64bit signature in the dwarf header should only affect references within the dwarf info. But by accident it affected constant addresses. This lead to truncation of some addresses, when dwarf-3 was used with 64 bit targets. ........ git-svn-id: branches/fixes_2_0@59785 - --- components/fpdebug/fpdbgdwarfdataclasses.pas | 52 +++++++++++++------ .../fpdebug/fpdbgdwarfverboseprinter.pas | 21 ++++++-- 2 files changed, 52 insertions(+), 21 deletions(-) diff --git a/components/fpdebug/fpdbgdwarfdataclasses.pas b/components/fpdebug/fpdbgdwarfdataclasses.pas index a0626d87f2..fe1e314d7b 100644 --- a/components/fpdebug/fpdbgdwarfdataclasses.pas +++ b/components/fpdebug/fpdbgdwarfdataclasses.pas @@ -535,7 +535,8 @@ type procedure BuildAddressMap; function GetAddressMap: TMap; function GetUnitName: String; - function ReadAddressAtPointer(var AData: Pointer; AIncPointer: Boolean = False): TFpDbgMemLocation; + function ReadTargetAddressFromDwarfSection(var AData: Pointer; AIncPointer: Boolean = False): TFpDbgMemLocation; + function ReadDwarfSectionOffsetOrLenFromDwarfSection(var AData: Pointer; AIncPointer: Boolean = False): TFpDbgMemLocation; protected function LocateEntry(ATag: Cardinal; out AResultScope: TDwarfScopeInfo): Boolean; function InitLocateAttributeList(AEntry: Pointer; var AList: TAttribPointerList): Boolean; @@ -576,6 +577,14 @@ type property Version: Word read FVersion; //property AbbrevOffset: QWord read FAbbrevOffset; property AddressSize: Byte read FAddressSize; // the address size of the target in bytes + (* IsDwarf64, From the spec: + In the 64-bit DWARF format, all values that + *** "represent lengths of DWARF sections and offsets relative to the beginning of DWARF sections" *** + are represented using 64-bits. + + A special convention applies to the initial length field of certain DWARF sections, as well as the CIE and FDE structures, + so that the 32-bit and 64-bit DWARF formats can coexist and be distinguished within a single linked object. + *) property IsDwarf64: Boolean read FIsDwarf64; // Set if the dwarf info in this unit is 64bit property Owner: TFpDwarfInfo read FOwner; property DebugFile: PDwarfDebugFile read FDebugFile; @@ -1858,7 +1867,7 @@ begin inc(CurData); case CurInstr^ of DW_OP_nop: ; - DW_OP_addr: FStack.Push(FCU.ReadAddressAtPointer(CurData, True), lseValue); + DW_OP_addr: FStack.Push(FCU.ReadTargetAddressFromDwarfSection(CurData, True), lseValue); DW_OP_deref: begin if not AssertAddressOnStack then exit; if not ReadAddressFromMemory(FStack.Pop.Value, AddrSize, NewLoc) then exit; @@ -3616,7 +3625,6 @@ constructor TDwarfCompilationUnit.Create(AOwner: TFpDwarfInfo; ADebugFile: PDwar then begin if FVersion < 3 then DebugLn(FPDBG_DWARF_WARNINGS, ['Unexpected 64 bit signature found for DWARF version 2']); // or version 1... - FLineInfo.Addr64 := True; UnitLength := LNP64^.UnitLength; FLineInfo.DataEnd := Pointer(@LNP64^.Version) + UnitLength; Version := LNP64^.Version; @@ -3624,10 +3632,6 @@ constructor TDwarfCompilationUnit.Create(AOwner: TFpDwarfInfo; ADebugFile: PDwar Info := @LNP64^.Info; end else begin - if (FVersion < 3) and (FAddressSize = 8) then - FLineInfo.Addr64 := True - else - FLineInfo.Addr64 := False; UnitLength := LNP32^.UnitLength; FLineInfo.DataEnd := Pointer(@LNP32^.Version) + UnitLength; Version := LNP32^.Version; @@ -3635,6 +3639,7 @@ constructor TDwarfCompilationUnit.Create(AOwner: TFpDwarfInfo; ADebugFile: PDwar Info := @LNP32^.Info; end; if Version=0 then ; + FLineInfo.Addr64 := FAddressSize = 8; FLineInfo.DataStart := PByte(Info) + HeaderLength; FLineInfo.MinimumInstructionLength := Info^.MinimumInstructionLength; @@ -4103,7 +4108,18 @@ begin end; -function TDwarfCompilationUnit.ReadAddressAtPointer(var AData: Pointer; +function TDwarfCompilationUnit.ReadTargetAddressFromDwarfSection(var AData: Pointer; + AIncPointer: Boolean): TFpDbgMemLocation; +begin + // do not need mem reader, address is in dwarf. Should be in correct format + if (FAddressSize = 8) then + Result := TargetLoc(PQWord(AData)^) + else + Result := TargetLoc(PLongWord(AData)^); + if AIncPointer then inc(AData, FAddressSize); +end; + +function TDwarfCompilationUnit.ReadDwarfSectionOffsetOrLenFromDwarfSection(var AData: Pointer; AIncPointer: Boolean): TFpDbgMemLocation; begin // do not need mem reader, address is in dwarf. Should be in correct format @@ -4141,9 +4157,10 @@ function TDwarfCompilationUnit.ReadValue(AAttribute: Pointer; AForm: Cardinal; o begin Result := True; case AForm of - DW_FORM_addr, + DW_FORM_addr: + AValue := LocToAddrOrNil(ReadTargetAddressFromDwarfSection(AAttribute)); DW_FORM_ref_addr : begin - AValue := LocToAddrOrNil(ReadAddressAtPointer(AAttribute)); + AValue := LocToAddrOrNil(ReadDwarfSectionOffsetOrLenFromDwarfSection(AAttribute)); end; DW_FORM_flag, DW_FORM_ref1, @@ -4178,9 +4195,10 @@ function TDwarfCompilationUnit.ReadValue(AAttribute: Pointer; AForm: Cardinal; o begin Result := True; case AForm of - DW_FORM_addr, + DW_FORM_addr: + AValue := LocToAddrOrNil(ReadTargetAddressFromDwarfSection(AAttribute)); DW_FORM_ref_addr : begin - AValue := LocToAddrOrNil(ReadAddressAtPointer(AAttribute)); + AValue := LocToAddrOrNil(ReadDwarfSectionOffsetOrLenFromDwarfSection(AAttribute)); end; DW_FORM_flag, DW_FORM_ref1, @@ -4215,9 +4233,10 @@ function TDwarfCompilationUnit.ReadValue(AAttribute: Pointer; AForm: Cardinal; o begin Result := True; case AForm of - DW_FORM_addr, + DW_FORM_addr: + AValue := LocToAddrOrNil(ReadTargetAddressFromDwarfSection(AAttribute)); DW_FORM_ref_addr : begin - AValue := LocToAddrOrNil(ReadAddressAtPointer(AAttribute)); + AValue := LocToAddrOrNil(ReadDwarfSectionOffsetOrLenFromDwarfSection(AAttribute)); end; DW_FORM_flag, DW_FORM_ref1, @@ -4267,9 +4286,10 @@ function TDwarfCompilationUnit.ReadValue(AAttribute: Pointer; AForm: Cardinal; o begin Result := True; case AForm of - DW_FORM_addr, + DW_FORM_addr: + AValue := LocToAddrOrNil(ReadTargetAddressFromDwarfSection(AAttribute)); DW_FORM_ref_addr : begin - AValue := LocToAddrOrNil(ReadAddressAtPointer(AAttribute)); + AValue := LocToAddrOrNil(ReadDwarfSectionOffsetOrLenFromDwarfSection(AAttribute)); end; DW_FORM_flag, DW_FORM_ref1, diff --git a/components/fpdebug/fpdbgdwarfverboseprinter.pas b/components/fpdebug/fpdbgdwarfverboseprinter.pas index d4f40f7051..be9b0d2cd7 100644 --- a/components/fpdebug/fpdbgdwarfverboseprinter.pas +++ b/components/fpdebug/fpdbgdwarfverboseprinter.pas @@ -15,7 +15,8 @@ type TDwarfAbbrevDecoder = class(TObject) private FCU: TDwarfCompilationUnit; - function ReadAddressAtPointer(var AData: Pointer; AIncPointer: Boolean = False): TFpDbgMemLocation; + function ReadTargetAddressFromDwarfSection(var AData: Pointer; AIncPointer: Boolean = False): TFpDbgMemLocation; + function ReadDwarfSectionOffsetOrLenFromDwarfSection(var AData: Pointer; AIncPointer: Boolean = False): TFpDbgMemLocation; procedure InternalDecode(AData: Pointer; AMaxData: Pointer; const AIndent: String = ''); protected procedure DecodeLocation(AData: PByte; ASize: QWord; const AIndent: String = ''); @@ -338,7 +339,17 @@ begin end; -function TDwarfAbbrevDecoder.ReadAddressAtPointer(var AData: Pointer; +function TDwarfAbbrevDecoder.ReadTargetAddressFromDwarfSection( + var AData: Pointer; AIncPointer: Boolean): TFpDbgMemLocation; +begin + // do not need mem reader, address is in dwarf. Should be in correct format + if FCU.AddressSize = 4 + then Result := TargetLoc(PLongWord(AData)^) + else Result := TargetLoc(PQWord(AData)^); + if AIncPointer then inc(AData, FCU.AddressSize); +end; + +function TDwarfAbbrevDecoder.ReadDwarfSectionOffsetOrLenFromDwarfSection(var AData: Pointer; AIncPointer: Boolean): TFpDbgMemLocation; begin // do not need mem reader, address is in dwarf. Should be in correct format @@ -434,7 +445,7 @@ p := AData; DbgOut(FPDBG_DWARF_VERBOSE, [', value: ']); case Form of DW_FORM_addr : begin - Value := LocToAddrOrNil(ReadAddressAtPointer(AData)); + Value := LocToAddrOrNil(ReadTargetAddressFromDwarfSection(AData)); ValuePtr := {%H-}Pointer(PtrUInt(Value)); ValueSize := FCU.AddressSize; DbgOut(FPDBG_DWARF_VERBOSE, ['$'+IntToHex(Value, FCU.AddressSize * 2)]); @@ -540,7 +551,7 @@ p := AData; DbgOut(FPDBG_DWARF_VERBOSE, ['$'+IntToHex(Value, ValueSize * 2)]); end; DW_FORM_ref_addr : begin - Value := LocToAddrOrNil(ReadAddressAtPointer(AData)); + Value := LocToAddrOrNil(ReadDwarfSectionOffsetOrLenFromDwarfSection(AData)); ValuePtr := {%H-}Pointer(PtrUInt(Value)); ValueSize := FCU.AddressSize; DbgOut(FPDBG_DWARF_VERBOSE, ['$'+IntToHex(Value, FCU.AddressSize * 2)]); @@ -552,7 +563,7 @@ p := AData; ValueSize := {%H-}PtrUInt(AData) - {%H-}PtrUInt(ValuePtr); end; DW_FORM_strp : begin - Value := LocToAddrOrNil(ReadAddressAtPointer(AData)); + Value := LocToAddrOrNil(ReadDwarfSectionOffsetOrLenFromDwarfSection(AData)); ValueSize := FCU.AddressSize; DbgOut(FPDBG_DWARF_VERBOSE, ['$'+IntToHex(Value, FCU.AddressSize * 2)]); Inc(AData, FCU.AddressSize);