View Issue Details

IDProjectCategoryView StatusLast Update
0036520FPCCompilerpublic2020-01-05 22:07
ReporterDaniel Glöckner Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Platformx86_64OSLinux 
Product Version3.3.1 
Summary0036520: Incorrect .debug_frame FDE entries on 64 bit architectures
DescriptionOn 64 architectures Free Pascal will emit FDE entries with 64 bit CIE_pointer values. This shifts the following fields by four bytes so that the FDE entries are no longer associated with the correct code regions.
DWARF 3 allows for 64 bit CIE_pointer values if the length value is also emitted as a 64 bit value and prefixed with $ffffffff. TDebugInfoDwarf has code to work in this 64 bit DWARF mode in other places, but TDwarfAsmCFILowLevel can't access that information. It looks like the 64 bit mode of TDebugInfoDwarf is never enabled anyway.
Steps To ReproduceCompile something with -gw for x86-64 Linux.
Use "readelf -wF" to look at the debug frame info.
The pc ranges for the FDE entries are all shifted by 32 bits.
Additional InformationThe attached patch works for me but should be changed to share its use_64bit_headers, offsetreltype, and offsetabstype variables with TDebugInfoDwarf.
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files

Activities

Daniel Glöckner

2020-01-05 22:07

reporter  

dwarf-fde-on-64-bit.patch (3,613 bytes)   
diff --git a/fpcsrc/compiler/cfidwarf.pas b/fpcsrc/compiler/cfidwarf.pas
index 6ed85e74..16fa863a 100644
--- a/fpcsrc/compiler/cfidwarf.pas
+++ b/fpcsrc/compiler/cfidwarf.pas
@@ -73,6 +73,9 @@ interface
         FFrameStartLabel,
         FFrameEndLabel,
         FLastloclabel : tasmlabel;
+        use_64bit_headers : Boolean;
+        offsetreltype,
+        offsetabstype : taiconst_type;
         procedure cfa_advance_loc(list:TAsmList);
         procedure generate_initial_instructions(list:TAsmList);virtual;
       protected
@@ -248,6 +251,17 @@ implementation
         code_alignment_factor:=1;
         data_alignment_factor:=-4;
         FDwarfList:=TAsmList.Create;
+
+        // FIXME: use values from dbgdwarf.pas
+        use_64bit_headers:=false;
+        if (target_info.system in systems_windows+systems_wince) then
+          offsetabstype:=aitconst_secrel32_symbol
+        else
+          offsetabstype:=aitconst_32bit_unaligned;
+        if (target_info.system in systems_darwin) then
+           offsetreltype:=aitconst_darwin_dwarf_delta32
+         else
+           offsetreltype:=aitconst_32bit_unaligned;
       end;
 
 
@@ -324,9 +338,11 @@ implementation
         }
         current_asmdata.getlabel(cielabel,alt_dbgframe);
         list.concat(tai_label.create(cielabel));
+        if use_64bit_headers then
+          list.concat(tai_const.create_32bit_unaligned(longint($FFFFFFFF)));
         current_asmdata.getlabel(lenstartlabel,alt_dbgframe);
         current_asmdata.getlabel(lenendlabel,alt_dbgframe);
-        list.concat(tai_const.create_rel_sym(aitconst_32bit,lenstartlabel,lenendlabel));
+        list.concat(tai_const.create_rel_sym(offsetreltype,lenstartlabel,lenendlabel));
         list.concat(tai_label.create(lenstartlabel));
         if use_eh_frame then
           begin
@@ -341,6 +357,8 @@ implementation
         else
           begin
             list.concat(tai_const.create_32bit(longint($ffffffff)));
+            if use_64bit_headers then
+              list.concat(tai_const.create_32bit(longint($ffffffff)));
             list.concat(tai_const.create_8bit(1));
             list.concat(tai_const.create_8bit(0)); { empty string }
           end;
@@ -399,7 +417,9 @@ implementation
                      PTRSIZE initial location = oper[0]
                      PTRSIZE function size = oper[1]
                   }
-                  list.concat(tai_const.create_rel_sym(aitconst_32bit,lenstartlabel,lenendlabel));
+                  if use_64bit_headers then
+                    list.concat(tai_const.create_32bit_unaligned(longint($FFFFFFFF)));
+                  list.concat(tai_const.create_rel_sym(offsetreltype,lenstartlabel,lenendlabel));
                   list.concat(tai_label.create(lenstartlabel));
                   if use_eh_frame then
                     begin
@@ -409,13 +429,7 @@ implementation
                       list.concat(tai_const.create_rel_sym(aitconst_32bit,cielabel,fdeofslabel));
                     end
                   else
-                    begin
-                      tc:=tai_const.create_sym(cielabel);
-                      { force label offset to secrel32 for windows systems }
-                      if (target_info.system in systems_windows+systems_wince) then
-                        tc.consttype:=aitconst_secrel32_symbol;
-                      list.concat(tc);
-                    end;
+                    list.concat(tai_const.create_type_sym(offsetabstype, cielabel));
 
                   current_asmdata.getlabel(curpos,alt_dbgframe);
                   list.concat(tai_label.create(curpos));
dwarf-fde-on-64-bit.patch (3,613 bytes)   

Issue History

Date Modified Username Field Change
2020-01-05 22:07 Daniel Glöckner New Issue
2020-01-05 22:07 Daniel Glöckner File Added: dwarf-fde-on-64-bit.patch