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:
Ingo Weinhold 2009-11-06 14:56:10 +00:00
parent 5f917b22c8
commit 797aaa4bde
2 changed files with 27 additions and 3 deletions

View File

@ -166,6 +166,7 @@ DwarfFile::DwarfFile()
fDebugPublicTypesSection(NULL),
fCompilationUnits(20, true),
fCurrentCompilationUnit(NULL),
fUsingEHFrameSection(false),
fFinished(false),
fFinishError(B_OK)
{
@ -223,6 +224,10 @@ DwarfFile::Load(const char* fileName)
fDebugRangesSection = fElfFile->GetSection(".debug_ranges");
fDebugLineSection = fElfFile->GetSection(".debug_line");
fDebugFrameSection = fElfFile->GetSection(".debug_frame");
if (fDebugFrameSection == NULL) {
fDebugFrameSection = fElfFile->GetSection(".eh_frame");
fUsingEHFrameSection = fDebugFrameSection != NULL;
}
fDebugLocationSection = fElfFile->GetSection(".debug_loc");
fDebugPublicTypesSection = fElfFile->GetSection(".debug_pubtypes");
@ -419,9 +424,11 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit,
DataReader dataReader((uint8*)fDebugFrameSection->Data(),
fDebugFrameSection->Size(), unit->AddressSize());
uint64 previousCIE = 0;
while (dataReader.BytesRemaining() > 0) {
// length
bool dwarf64;
off_t entryOffset = dataReader.Offset();
uint64 length = dataReader.ReadInitialLength(dwarf64);
if (length > (uint64)dataReader.BytesRemaining())
return B_BAD_DATA;
@ -430,8 +437,13 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit,
// CIE ID/CIE pointer
uint64 cieID = dwarf64
? 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
previousCIE = entryOffset;
} else {
// this is a FDE
target_addr_t initialLocation = dataReader.ReadAddress(0);
@ -448,6 +460,12 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit,
if (remaining < 0)
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, "
"location: %#llx, range: %#llx\n", length, remaining, cieID,
initialLocation, addressRange);
@ -1367,8 +1385,13 @@ DwarfFile::_ParseCIE(CompilationUnit* unit, CfaContext& context,
// CIE ID/CIE pointer
uint64 cieID = dwarf64
? dataReader.Read<uint64>(0) : dataReader.Read<uint32>(0);
if (dwarf64 ? cieID != 0xffffffffffffffffULL : cieID != 0xffffffff)
return B_BAD_DATA;
if (fUsingEHFrameSection) {
if (cieID != 0)
return B_BAD_DATA;
} else {
if (dwarf64 ? cieID != 0xffffffffffffffffULL : cieID != 0xffffffff)
return B_BAD_DATA;
}
uint8 version = dataReader.Read<uint8>(0);
const char* augmentation = dataReader.ReadString();

View File

@ -153,6 +153,7 @@ private:
DebugInfoEntryFactory fDebugInfoFactory;
CompilationUnitList fCompilationUnits;
CompilationUnit* fCurrentCompilationUnit;
bool fUsingEHFrameSection;
bool fFinished;
status_t fFinishError;
};