public StackFrame UnwindStack(StackFrame frame, TargetMemoryAccess target, Architecture arch) { if (frame.TargetAddress.IsNull) return null; TargetAddress address = frame.TargetAddress; DwarfBinaryReader reader = new DwarfBinaryReader (bfd, blob, false); while (reader.Position < reader.Size) { long length = reader.ReadInitialLength (); if (length == 0) break; long end_pos = reader.Position + length; long cie_pointer = reader.ReadOffset (); bool is_cie; if (is_ehframe) is_cie = cie_pointer == 0; else is_cie = cie_pointer == -1; if (is_cie) { reader.Position = end_pos; continue; } if (is_ehframe) cie_pointer = reader.Position - cie_pointer - target.TargetMemoryInfo.TargetAddressSize; CIE cie = find_cie (cie_pointer); long initial, range; if (is_ehframe) { initial = ReadEncodedValue (reader, cie.Encoding); range = ReadEncodedValue (reader, cie.Encoding & 0x0f); } else { initial = reader.ReadAddress (); range = reader.ReadAddress (); } TargetAddress start = new TargetAddress (target.AddressDomain, initial); if ((address < start) || (address > start + range)) { reader.Position = end_pos; continue; } Entry fde = new Entry (cie, start, address); fde.Read (reader, end_pos); return fde.Unwind (frame, target, arch); } return null; }
void read_cie(DwarfBinaryReader reader) { long length = reader.ReadInitialLength (); long end_pos = reader.Position + length; int id = reader.ReadInt32 (); bool is_cie; if (frame.is_ehframe) is_cie = id == 0; else is_cie = id == -1; if (!is_cie) throw new InvalidOperationException (); int version = reader.ReadByte (); if (version != 1) throw new DwarfException ( reader.Bfd, "Unknown version {0} in CIE", version); string augmentation = reader.ReadString (); if (augmentation.StartsWith ("eh")) { reader.ReadAddress (); augmentation = augmentation.Substring (2); } code_alignment = reader.ReadLeb128 (); data_alignment = reader.ReadSLeb128 (); return_register = reader.ReadByte (); for (int pos = 0; pos < augmentation.Length; pos++) { if (augmentation [pos] == 'z') { reader.ReadLeb128 (); // has_z_augmentation = true; continue; } if (augmentation [pos] == 'L') continue; else if (augmentation [pos] == 'R') { encoding = reader.ReadByte (); continue; } else if (augmentation [pos] == 'P') { continue; } throw new DwarfException ( reader.Bfd, "Unknown augmentation `{0}' in CIE", augmentation[pos]); } columns = new Column [return_register + 2]; for (int i = 0; i < columns.Length; i++) columns [i] = new Column (State.Undefined); Entry entry = new Entry (this); entry.Read (reader, end_pos); reader.Position = end_pos; }
ArrayList read_aranges() { ArrayList ranges = new ArrayList (); if (debug_aranges_reader == null) return ranges; DwarfBinaryReader reader = new DwarfBinaryReader ( bfd, (TargetBlob) debug_aranges_reader.Data, Is64Bit); while (!reader.IsEof) { long length = reader.ReadInitialLength (); long stop = reader.Position + length; int version = reader.ReadInt16 (); long offset = reader.ReadOffset (); int address_size = reader.ReadByte (); int segment_size = reader.ReadByte (); if ((address_size != 4) && (address_size != 8)) throw new DwarfException ( bfd, "Unknown address size: {0}", address_size); if (segment_size != 0) throw new DwarfException ( bfd, "Segmented address mode not supported"); if (version != 2) throw new DwarfException ( bfd, "Wrong version in .debug_aranges: {0}", version); if (AddressSize == 8) reader.Position = ((reader.Position+15) >> 4) * 16; else reader.Position = ((reader.Position+7) >> 3) * 8; while (reader.Position < stop) { long address = reader.ReadAddress (); long size = reader.ReadAddress (); if ((address == 0) && (size == 0)) break; TargetAddress taddress = GetAddress (address); ranges.Add (new RangeEntry (this, offset, taddress, size)); } } return ranges; }