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:
parent
5f917b22c8
commit
797aaa4bde
@ -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();
|
||||
|
@ -153,6 +153,7 @@ private:
|
||||
DebugInfoEntryFactory fDebugInfoFactory;
|
||||
CompilationUnitList fCompilationUnits;
|
||||
CompilationUnit* fCurrentCompilationUnit;
|
||||
bool fUsingEHFrameSection;
|
||||
bool fFinished;
|
||||
status_t fFinishError;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user