gcc 2.95.3 doesn't generate a .debug_frame section. Fortunately it generates a
.eh_frame section which seems to have almost identical contents (haven't found any specification). So now we use .eh_frame with minor tweaks, when .debug_frame is not available. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33914 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -166,6 +166,7 @@ DwarfFile::DwarfFile()
|
|||||||
fDebugPublicTypesSection(NULL),
|
fDebugPublicTypesSection(NULL),
|
||||||
fCompilationUnits(20, true),
|
fCompilationUnits(20, true),
|
||||||
fCurrentCompilationUnit(NULL),
|
fCurrentCompilationUnit(NULL),
|
||||||
|
fUsingEHFrameSection(false),
|
||||||
fFinished(false),
|
fFinished(false),
|
||||||
fFinishError(B_OK)
|
fFinishError(B_OK)
|
||||||
{
|
{
|
||||||
@@ -223,6 +224,10 @@ DwarfFile::Load(const char* fileName)
|
|||||||
fDebugRangesSection = fElfFile->GetSection(".debug_ranges");
|
fDebugRangesSection = fElfFile->GetSection(".debug_ranges");
|
||||||
fDebugLineSection = fElfFile->GetSection(".debug_line");
|
fDebugLineSection = fElfFile->GetSection(".debug_line");
|
||||||
fDebugFrameSection = fElfFile->GetSection(".debug_frame");
|
fDebugFrameSection = fElfFile->GetSection(".debug_frame");
|
||||||
|
if (fDebugFrameSection == NULL) {
|
||||||
|
fDebugFrameSection = fElfFile->GetSection(".eh_frame");
|
||||||
|
fUsingEHFrameSection = fDebugFrameSection != NULL;
|
||||||
|
}
|
||||||
fDebugLocationSection = fElfFile->GetSection(".debug_loc");
|
fDebugLocationSection = fElfFile->GetSection(".debug_loc");
|
||||||
fDebugPublicTypesSection = fElfFile->GetSection(".debug_pubtypes");
|
fDebugPublicTypesSection = fElfFile->GetSection(".debug_pubtypes");
|
||||||
|
|
||||||
@@ -419,9 +424,11 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit,
|
|||||||
DataReader dataReader((uint8*)fDebugFrameSection->Data(),
|
DataReader dataReader((uint8*)fDebugFrameSection->Data(),
|
||||||
fDebugFrameSection->Size(), unit->AddressSize());
|
fDebugFrameSection->Size(), unit->AddressSize());
|
||||||
|
|
||||||
|
uint64 previousCIE = 0;
|
||||||
while (dataReader.BytesRemaining() > 0) {
|
while (dataReader.BytesRemaining() > 0) {
|
||||||
// length
|
// length
|
||||||
bool dwarf64;
|
bool dwarf64;
|
||||||
|
off_t entryOffset = dataReader.Offset();
|
||||||
uint64 length = dataReader.ReadInitialLength(dwarf64);
|
uint64 length = dataReader.ReadInitialLength(dwarf64);
|
||||||
if (length > (uint64)dataReader.BytesRemaining())
|
if (length > (uint64)dataReader.BytesRemaining())
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
@@ -430,8 +437,13 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit,
|
|||||||
// CIE ID/CIE pointer
|
// CIE ID/CIE pointer
|
||||||
uint64 cieID = dwarf64
|
uint64 cieID = dwarf64
|
||||||
? dataReader.Read<uint64>(0) : dataReader.Read<uint32>(0);
|
? dataReader.Read<uint64>(0) : dataReader.Read<uint32>(0);
|
||||||
if (dwarf64 ? cieID == 0xffffffffffffffffULL : cieID == 0xffffffff) {
|
if (fUsingEHFrameSection
|
||||||
|
? cieID == 0
|
||||||
|
: (dwarf64
|
||||||
|
? cieID == 0xffffffffffffffffULL
|
||||||
|
: cieID == 0xffffffff)) {
|
||||||
// this is a CIE -- skip it
|
// this is a CIE -- skip it
|
||||||
|
previousCIE = entryOffset;
|
||||||
} else {
|
} else {
|
||||||
// this is a FDE
|
// this is a FDE
|
||||||
target_addr_t initialLocation = dataReader.ReadAddress(0);
|
target_addr_t initialLocation = dataReader.ReadAddress(0);
|
||||||
@@ -448,6 +460,12 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit,
|
|||||||
if (remaining < 0)
|
if (remaining < 0)
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
|
// For some reason gcc 2.95.3 doesn't write the CIE offset, but
|
||||||
|
// always the offset of this entry's CIE pointer field. We fix
|
||||||
|
// it.
|
||||||
|
if (fUsingEHFrameSection && cieID == (uint64)lengthOffset)
|
||||||
|
cieID = previousCIE;
|
||||||
|
|
||||||
TRACE_CFI(" found fde: length: %llu (%lld), CIE offset: %llu, "
|
TRACE_CFI(" found fde: length: %llu (%lld), CIE offset: %llu, "
|
||||||
"location: %#llx, range: %#llx\n", length, remaining, cieID,
|
"location: %#llx, range: %#llx\n", length, remaining, cieID,
|
||||||
initialLocation, addressRange);
|
initialLocation, addressRange);
|
||||||
@@ -1367,8 +1385,13 @@ DwarfFile::_ParseCIE(CompilationUnit* unit, CfaContext& context,
|
|||||||
// CIE ID/CIE pointer
|
// CIE ID/CIE pointer
|
||||||
uint64 cieID = dwarf64
|
uint64 cieID = dwarf64
|
||||||
? dataReader.Read<uint64>(0) : dataReader.Read<uint32>(0);
|
? dataReader.Read<uint64>(0) : dataReader.Read<uint32>(0);
|
||||||
if (dwarf64 ? cieID != 0xffffffffffffffffULL : cieID != 0xffffffff)
|
if (fUsingEHFrameSection) {
|
||||||
return B_BAD_DATA;
|
if (cieID != 0)
|
||||||
|
return B_BAD_DATA;
|
||||||
|
} else {
|
||||||
|
if (dwarf64 ? cieID != 0xffffffffffffffffULL : cieID != 0xffffffff)
|
||||||
|
return B_BAD_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
uint8 version = dataReader.Read<uint8>(0);
|
uint8 version = dataReader.Read<uint8>(0);
|
||||||
const char* augmentation = dataReader.ReadString();
|
const char* augmentation = dataReader.ReadString();
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ private:
|
|||||||
DebugInfoEntryFactory fDebugInfoFactory;
|
DebugInfoEntryFactory fDebugInfoFactory;
|
||||||
CompilationUnitList fCompilationUnits;
|
CompilationUnitList fCompilationUnits;
|
||||||
CompilationUnit* fCurrentCompilationUnit;
|
CompilationUnit* fCurrentCompilationUnit;
|
||||||
|
bool fUsingEHFrameSection;
|
||||||
bool fFinished;
|
bool fFinished;
|
||||||
status_t fFinishError;
|
status_t fFinishError;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user