Class: ElfUtils::Section::DebugInfo::CompilationUnit

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
CTypes::Helpers
Defined in:
lib/elf_utils/section/debug_info/compilation_unit.rb

Constant Summary collapse

ULEB128 =
Types::ULEB128

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file, offset, header) ⇒ CompilationUnit

Returns a new instance of CompilationUnit.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 10

def initialize(file, offset, header)
  @file = file
  @offset = offset
  @header = header
  @debug_str = @file.section(".debug_str")

  @endian = @file.endian
  @addr_size = header.addr_size
  @addr_type = case header.addr_size
  when 4
    uint32.with_endian(@endian)
  when 8
    uint64.with_endian(@endian)
  else
    raise Error,
      "unsupported address size in DWARF header: %p" % [@header]
  end
  @offset_type = (header.format == :dwarf32) ?
    uint32.with_endian(@endian) :
    uint64.with_endian(@endian)

  @types = {}
end

Instance Attribute Details

#addr_typeObject (readonly)

Returns the value of attribute addr_type.



33
34
35
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 33

def addr_type
  @addr_type
end

#fileObject (readonly)

Returns the value of attribute file.



33
34
35
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 33

def file
  @file
end

#offsetObject (readonly)

Returns the value of attribute offset.



33
34
35
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 33

def offset
  @offset
end

#offset_typeObject (readonly)

Returns the value of attribute offset_type.



33
34
35
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 33

def offset_type
  @offset_type
end

Instance Method Details

#abbrev_tableObject



49
50
51
52
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 49

def abbrev_table
  @abbrev_table ||= file.section(".debug_abbrev")
    .abbreviation_table(@header.debug_abbrev_offset)
end

#addr_baseObject

helper for accessing DW_TAG_addr_base in the CU DIE



130
131
132
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 130

def addr_base
  @addr_base ||= root_die.raw_attr(:addr_base)
end

#debug_addr_get!(index) ⇒ Object

helper for Types::Dwarf::Expression to get values from the .debug_addr section.

Parameters:

  • index (Integer)

    index into the .debug_addr section to be adjusted by the base for this CompilationUnit



112
113
114
115
116
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 112

def debug_addr_get!(index)
  debug_addr = @file.section(".debug_addr") or
    raise Error, "`.debug_addr` section not present in #{@file}"
  debug_addr.get(base: root_die[:addr_base], index:)
end

#debug_str_offsetsObject

helper for DIEs to get easy access to .debug_str_offsets & base



119
120
121
122
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 119

def debug_str_offsets
  @debug_str_offsets ||=
    [@file.section(".debug_str_offsets"), root_die[:str_offsets_base]]
end

#die(offset) ⇒ Object



65
66
67
68
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 65

def die(offset)
  @dies ||= split_dies
  @dies[offset] or raise Error, "invalid DIE offset: 0x%x" % offset
end

#die_rangeObject



54
55
56
57
58
59
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 54

def die_range
  @range ||= begin
    start = @offset + @header.class.size
    start...start + @header.data.size
  end
end

#diesObject



70
71
72
73
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 70

def dies
  @dies ||= split_dies
  @dies.values
end

#include_addr?(addr) ⇒ Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 134

def include_addr?(addr)
  root_die.addr_ranges&.any? { |r| r.include?(addr) }
end

#inspectObject



40
41
42
43
44
45
46
47
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 40

def inspect
  fmt = <<~FMT.chomp
    <%s offset=0x%x, size=%d, format=%p, version=%d, abbr_offset=0x%x, \
    addr_size=%d>
  FMT
  fmt %
    [self.class, offset, size, format, version, abbr_offset, addr_size]
end

#root_dieObject



61
62
63
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 61

def root_die
  dies.first
end

#str_offsets_baseObject

helper for accessing DW_TAG_str_offsets_base in the CU DIE



125
126
127
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 125

def str_offsets_base
  @str_offsets_base ||= root_die.raw_attr(:str_offsets_base)
end

#type(arg) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 86

def type(arg)
  case arg
  when Integer
    _, t = die(arg).ctype
    t
  when String
    # check the cache first
    if (type = @types[arg])
      return type
    end

    # then try finding the die with the type
    dies.each do |die|
      next unless die.type_name == arg
      @types[arg] = die.ctype
    end
    @types[arg]
  else
    raise Error, "unsupported type lookup key: %p" % [arg]
  end
end

#typesObject



75
76
77
78
79
80
81
82
83
84
# File 'lib/elf_utils/section/debug_info/compilation_unit.rb', line 75

def types
  unless @cached_all_types
    dies.each do |die|
      name = die.type_name or next
      @types[name] ||= die.ctype
    end
    @cached_all_types = true
  end
  @types
end