xref: /dflybsd-src/contrib/binutils-2.27/gold/dwarf_reader.h (revision 8c87cab6fe2117123ff265f00bfec80da0eb4bfc)
1a9fa9459Szrj // dwarf_reader.h -- parse dwarf2/3 debug information for gold  -*- C++ -*-
2a9fa9459Szrj 
3a9fa9459Szrj // Copyright (C) 2007-2016 Free Software Foundation, Inc.
4a9fa9459Szrj // Written by Ian Lance Taylor <iant@google.com>.
5a9fa9459Szrj 
6a9fa9459Szrj // This file is part of gold.
7a9fa9459Szrj 
8a9fa9459Szrj // This program is free software; you can redistribute it and/or modify
9a9fa9459Szrj // it under the terms of the GNU General Public License as published by
10a9fa9459Szrj // the Free Software Foundation; either version 3 of the License, or
11a9fa9459Szrj // (at your option) any later version.
12a9fa9459Szrj 
13a9fa9459Szrj // This program is distributed in the hope that it will be useful,
14a9fa9459Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
15a9fa9459Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16a9fa9459Szrj // GNU General Public License for more details.
17a9fa9459Szrj 
18a9fa9459Szrj // You should have received a copy of the GNU General Public License
19a9fa9459Szrj // along with this program; if not, write to the Free Software
20a9fa9459Szrj // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21a9fa9459Szrj // MA 02110-1301, USA.
22a9fa9459Szrj 
23a9fa9459Szrj #ifndef GOLD_DWARF_READER_H
24a9fa9459Szrj #define GOLD_DWARF_READER_H
25a9fa9459Szrj 
26a9fa9459Szrj #include <vector>
27a9fa9459Szrj #include <map>
28a9fa9459Szrj #include <limits.h>
29a9fa9459Szrj #include <sys/types.h>
30a9fa9459Szrj 
31a9fa9459Szrj #include "elfcpp.h"
32a9fa9459Szrj #include "elfcpp_swap.h"
33a9fa9459Szrj #include "dwarf.h"
34a9fa9459Szrj #include "reloc.h"
35a9fa9459Szrj 
36a9fa9459Szrj namespace gold
37a9fa9459Szrj {
38a9fa9459Szrj 
39a9fa9459Szrj class Dwarf_info_reader;
40a9fa9459Szrj struct LineStateMachine;
41a9fa9459Szrj 
42a9fa9459Szrj // This class is used to extract the section index and offset of
43a9fa9459Szrj // the target of a relocation for a given offset within the section.
44a9fa9459Szrj 
45a9fa9459Szrj class Elf_reloc_mapper
46a9fa9459Szrj {
47a9fa9459Szrj  public:
Elf_reloc_mapper()48a9fa9459Szrj   Elf_reloc_mapper()
49a9fa9459Szrj   { }
50a9fa9459Szrj 
51a9fa9459Szrj   virtual
~Elf_reloc_mapper()52a9fa9459Szrj   ~Elf_reloc_mapper()
53a9fa9459Szrj   { }
54a9fa9459Szrj 
55a9fa9459Szrj   // Initialize the relocation tracker for section RELOC_SHNDX.
56a9fa9459Szrj   bool
initialize(unsigned int reloc_shndx,unsigned int reloc_type)57a9fa9459Szrj   initialize(unsigned int reloc_shndx, unsigned int reloc_type)
58a9fa9459Szrj   { return this->do_initialize(reloc_shndx, reloc_type); }
59a9fa9459Szrj 
60a9fa9459Szrj   // Return the next reloc_offset.
61a9fa9459Szrj   off_t
next_offset()62a9fa9459Szrj   next_offset()
63a9fa9459Szrj   { return this->do_next_offset(); }
64a9fa9459Szrj 
65a9fa9459Szrj   // Advance to the next relocation past OFFSET.
66a9fa9459Szrj   void
advance(off_t offset)67a9fa9459Szrj   advance(off_t offset)
68a9fa9459Szrj   { this->do_advance(offset); }
69a9fa9459Szrj 
70a9fa9459Szrj   // Return the section index and offset within the section of the target
71a9fa9459Szrj   // of the relocation for RELOC_OFFSET in the referring section.
72a9fa9459Szrj   unsigned int
get_reloc_target(off_t reloc_offset,off_t * target_offset)73a9fa9459Szrj   get_reloc_target(off_t reloc_offset, off_t* target_offset)
74a9fa9459Szrj   { return this->do_get_reloc_target(reloc_offset, target_offset); }
75a9fa9459Szrj 
76a9fa9459Szrj   // Checkpoint the current position in the reloc section.
77a9fa9459Szrj   uint64_t
checkpoint()78a9fa9459Szrj   checkpoint() const
79a9fa9459Szrj   { return this->do_checkpoint(); }
80a9fa9459Szrj 
81a9fa9459Szrj   // Reset the current position to the CHECKPOINT.
82a9fa9459Szrj   void
reset(uint64_t checkpoint)83a9fa9459Szrj   reset(uint64_t checkpoint)
84a9fa9459Szrj   { this->do_reset(checkpoint); }
85a9fa9459Szrj 
86a9fa9459Szrj  protected:
87a9fa9459Szrj   virtual bool
88a9fa9459Szrj   do_initialize(unsigned int, unsigned int) = 0;
89a9fa9459Szrj 
90a9fa9459Szrj   // Return the next reloc_offset.
91a9fa9459Szrj   virtual off_t
92a9fa9459Szrj   do_next_offset() = 0;
93a9fa9459Szrj 
94a9fa9459Szrj   // Advance to the next relocation past OFFSET.
95a9fa9459Szrj   virtual void
96a9fa9459Szrj   do_advance(off_t offset) = 0;
97a9fa9459Szrj 
98a9fa9459Szrj   virtual unsigned int
99a9fa9459Szrj   do_get_reloc_target(off_t reloc_offset, off_t* target_offset) = 0;
100a9fa9459Szrj 
101a9fa9459Szrj   // Checkpoint the current position in the reloc section.
102a9fa9459Szrj   virtual uint64_t
103a9fa9459Szrj   do_checkpoint() const = 0;
104a9fa9459Szrj 
105a9fa9459Szrj   // Reset the current position to the CHECKPOINT.
106a9fa9459Szrj   virtual void
107a9fa9459Szrj   do_reset(uint64_t checkpoint) = 0;
108a9fa9459Szrj };
109a9fa9459Szrj 
110a9fa9459Szrj template<int size, bool big_endian>
111a9fa9459Szrj class Sized_elf_reloc_mapper : public Elf_reloc_mapper
112a9fa9459Szrj {
113a9fa9459Szrj  public:
Sized_elf_reloc_mapper(Object * object,const unsigned char * symtab,off_t symtab_size)114a9fa9459Szrj   Sized_elf_reloc_mapper(Object* object, const unsigned char* symtab,
115a9fa9459Szrj 			 off_t symtab_size)
116a9fa9459Szrj     : object_(object), symtab_(symtab), symtab_size_(symtab_size),
117a9fa9459Szrj       reloc_type_(0), track_relocs_()
118a9fa9459Szrj   { }
119a9fa9459Szrj 
120a9fa9459Szrj  protected:
121a9fa9459Szrj   bool
122a9fa9459Szrj   do_initialize(unsigned int reloc_shndx, unsigned int reloc_type);
123a9fa9459Szrj 
124a9fa9459Szrj   // Return the next reloc_offset.
125a9fa9459Szrj   virtual off_t
do_next_offset()126a9fa9459Szrj   do_next_offset()
127a9fa9459Szrj   { return this->track_relocs_.next_offset(); }
128a9fa9459Szrj 
129a9fa9459Szrj   // Advance to the next relocation past OFFSET.
130a9fa9459Szrj   virtual void
do_advance(off_t offset)131a9fa9459Szrj   do_advance(off_t offset)
132a9fa9459Szrj   { this->track_relocs_.advance(offset); }
133a9fa9459Szrj 
134a9fa9459Szrj   unsigned int
135a9fa9459Szrj   do_get_reloc_target(off_t reloc_offset, off_t* target_offset);
136a9fa9459Szrj 
137a9fa9459Szrj   // Checkpoint the current position in the reloc section.
138a9fa9459Szrj   uint64_t
do_checkpoint()139a9fa9459Szrj   do_checkpoint() const
140a9fa9459Szrj   { return this->track_relocs_.checkpoint(); }
141a9fa9459Szrj 
142a9fa9459Szrj   // Reset the current position to the CHECKPOINT.
143a9fa9459Szrj   void
do_reset(uint64_t checkpoint)144a9fa9459Szrj   do_reset(uint64_t checkpoint)
145a9fa9459Szrj   { this->track_relocs_.reset(checkpoint); }
146a9fa9459Szrj 
147a9fa9459Szrj  private:
148a9fa9459Szrj   typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
149a9fa9459Szrj 
150a9fa9459Szrj   // Return the section index of symbol SYMNDX, and copy its value to *VALUE.
151a9fa9459Szrj   // Set *IS_ORDINARY true if the section index is an ordinary section index.
152a9fa9459Szrj   unsigned int
153a9fa9459Szrj   symbol_section(unsigned int symndx, Address* value, bool* is_ordinary);
154a9fa9459Szrj 
155a9fa9459Szrj   // The object file.
156a9fa9459Szrj   Object* object_;
157a9fa9459Szrj   // The ELF symbol table.
158a9fa9459Szrj   const unsigned char* symtab_;
159a9fa9459Szrj   // The size of the ELF symbol table.
160a9fa9459Szrj   off_t symtab_size_;
161a9fa9459Szrj   // Type of the relocation section (SHT_REL or SHT_RELA).
162a9fa9459Szrj   unsigned int reloc_type_;
163a9fa9459Szrj   // Relocations for the referring section.
164a9fa9459Szrj   Track_relocs<size, big_endian> track_relocs_;
165a9fa9459Szrj };
166a9fa9459Szrj 
167a9fa9459Szrj // This class is used to read the abbreviations table from the
168a9fa9459Szrj // .debug_abbrev section of the object file.
169a9fa9459Szrj 
170a9fa9459Szrj class Dwarf_abbrev_table
171a9fa9459Szrj {
172a9fa9459Szrj  public:
173a9fa9459Szrj   // An attribute list entry.
174a9fa9459Szrj   struct Attribute
175a9fa9459Szrj   {
AttributeAttribute176a9fa9459Szrj     Attribute(unsigned int a, unsigned int f)
177a9fa9459Szrj       : attr(a), form(f)
178a9fa9459Szrj     { }
179a9fa9459Szrj     unsigned int attr;
180a9fa9459Szrj     unsigned int form;
181a9fa9459Szrj   };
182a9fa9459Szrj 
183a9fa9459Szrj   // An abbrev code entry.
184a9fa9459Szrj   struct Abbrev_code
185a9fa9459Szrj   {
Abbrev_codeAbbrev_code186a9fa9459Szrj     Abbrev_code(unsigned int t, bool hc)
187a9fa9459Szrj       : tag(t), has_children(hc), has_sibling_attribute(false), attributes()
188a9fa9459Szrj     {
189a9fa9459Szrj       this->attributes.reserve(10);
190a9fa9459Szrj     }
191a9fa9459Szrj 
192a9fa9459Szrj     void
add_attributeAbbrev_code193a9fa9459Szrj     add_attribute(unsigned int attr, unsigned int form)
194a9fa9459Szrj     {
195a9fa9459Szrj       this->attributes.push_back(Attribute(attr, form));
196a9fa9459Szrj     }
197a9fa9459Szrj 
198a9fa9459Szrj     // The DWARF tag.
199a9fa9459Szrj     unsigned int tag;
200a9fa9459Szrj     // True if the DIE has children.
201a9fa9459Szrj     bool has_children : 1;
202a9fa9459Szrj     // True if the DIE has a sibling attribute.
203a9fa9459Szrj     bool has_sibling_attribute : 1;
204a9fa9459Szrj     // The list of attributes and forms.
205a9fa9459Szrj     std::vector<Attribute> attributes;
206a9fa9459Szrj   };
207a9fa9459Szrj 
Dwarf_abbrev_table()208a9fa9459Szrj   Dwarf_abbrev_table()
209a9fa9459Szrj     : abbrev_shndx_(0), abbrev_offset_(0), buffer_(NULL), buffer_end_(NULL),
210a9fa9459Szrj       owns_buffer_(false), buffer_pos_(NULL), high_abbrev_codes_()
211a9fa9459Szrj   {
212a9fa9459Szrj     memset(this->low_abbrev_codes_, 0, sizeof(this->low_abbrev_codes_));
213a9fa9459Szrj   }
214a9fa9459Szrj 
~Dwarf_abbrev_table()215a9fa9459Szrj   ~Dwarf_abbrev_table()
216a9fa9459Szrj   {
217a9fa9459Szrj     if (this->owns_buffer_ && this->buffer_ != NULL)
218a9fa9459Szrj       delete[] this->buffer_;
219a9fa9459Szrj     this->clear_abbrev_codes();
220a9fa9459Szrj   }
221a9fa9459Szrj 
222a9fa9459Szrj   // Read the abbrev table from an object file.
223a9fa9459Szrj   bool
read_abbrevs(Relobj * object,unsigned int abbrev_shndx,off_t abbrev_offset)224a9fa9459Szrj   read_abbrevs(Relobj* object,
225a9fa9459Szrj 	       unsigned int abbrev_shndx,
226a9fa9459Szrj 	       off_t abbrev_offset)
227a9fa9459Szrj   {
228a9fa9459Szrj     // If we've already read this abbrev table, return immediately.
229a9fa9459Szrj     if (this->abbrev_shndx_ > 0
230a9fa9459Szrj 	&& this->abbrev_shndx_ == abbrev_shndx
231a9fa9459Szrj 	&& this->abbrev_offset_ == abbrev_offset)
232a9fa9459Szrj       return true;
233a9fa9459Szrj     return this->do_read_abbrevs(object, abbrev_shndx, abbrev_offset);
234a9fa9459Szrj   }
235a9fa9459Szrj 
236a9fa9459Szrj   // Return the abbrev code entry for CODE.  This is a fast path for
237a9fa9459Szrj   // abbrev codes that are in the direct lookup table.  If not found
238a9fa9459Szrj   // there, we call do_get_abbrev() to do the hard work.
239a9fa9459Szrj   const Abbrev_code*
get_abbrev(unsigned int code)240a9fa9459Szrj   get_abbrev(unsigned int code)
241a9fa9459Szrj   {
242a9fa9459Szrj     if (code < this->low_abbrev_code_max_
243a9fa9459Szrj 	&& this->low_abbrev_codes_[code] != NULL)
244a9fa9459Szrj       return this->low_abbrev_codes_[code];
245a9fa9459Szrj     return this->do_get_abbrev(code);
246a9fa9459Szrj   }
247a9fa9459Szrj 
248a9fa9459Szrj  private:
249a9fa9459Szrj   // Read the abbrev table from an object file.
250a9fa9459Szrj   bool
251a9fa9459Szrj   do_read_abbrevs(Relobj* object,
252a9fa9459Szrj 		  unsigned int abbrev_shndx,
253a9fa9459Szrj 		  off_t abbrev_offset);
254a9fa9459Szrj 
255a9fa9459Szrj   // Lookup the abbrev code entry for CODE.
256a9fa9459Szrj   const Abbrev_code*
257a9fa9459Szrj   do_get_abbrev(unsigned int code);
258a9fa9459Szrj 
259a9fa9459Szrj   // Store an abbrev code entry for CODE.
260a9fa9459Szrj   void
store_abbrev(unsigned int code,const Abbrev_code * entry)261a9fa9459Szrj   store_abbrev(unsigned int code, const Abbrev_code* entry)
262a9fa9459Szrj   {
263a9fa9459Szrj     if (code < this->low_abbrev_code_max_)
264a9fa9459Szrj       this->low_abbrev_codes_[code] = entry;
265a9fa9459Szrj     else
266a9fa9459Szrj       this->high_abbrev_codes_[code] = entry;
267a9fa9459Szrj   }
268a9fa9459Szrj 
269a9fa9459Szrj   // Clear the abbrev code table and release the memory it uses.
270a9fa9459Szrj   void
271a9fa9459Szrj   clear_abbrev_codes();
272a9fa9459Szrj 
273a9fa9459Szrj   typedef Unordered_map<unsigned int, const Abbrev_code*> Abbrev_code_table;
274a9fa9459Szrj 
275a9fa9459Szrj   // The section index of the current abbrev table.
276a9fa9459Szrj   unsigned int abbrev_shndx_;
277a9fa9459Szrj   // The offset within the section of the current abbrev table.
278a9fa9459Szrj   off_t abbrev_offset_;
279a9fa9459Szrj   // The buffer containing the .debug_abbrev section.
280a9fa9459Szrj   const unsigned char* buffer_;
281a9fa9459Szrj   const unsigned char* buffer_end_;
282a9fa9459Szrj   // True if this object owns the buffer and needs to delete it.
283a9fa9459Szrj   bool owns_buffer_;
284a9fa9459Szrj   // Pointer to the current position in the buffer.
285a9fa9459Szrj   const unsigned char* buffer_pos_;
286a9fa9459Szrj   // The table of abbrev codes.
287a9fa9459Szrj   // We use a direct-lookup array for low abbrev codes,
288a9fa9459Szrj   // and store the rest in a hash table.
289a9fa9459Szrj   static const unsigned int low_abbrev_code_max_ = 256;
290a9fa9459Szrj   const Abbrev_code* low_abbrev_codes_[low_abbrev_code_max_];
291a9fa9459Szrj   Abbrev_code_table high_abbrev_codes_;
292a9fa9459Szrj };
293a9fa9459Szrj 
294a9fa9459Szrj // A DWARF range list.  The start and end offsets are relative
295a9fa9459Szrj // to the input section SHNDX.  Each range must lie entirely
296a9fa9459Szrj // within a single section.
297a9fa9459Szrj 
298a9fa9459Szrj class Dwarf_range_list
299a9fa9459Szrj {
300a9fa9459Szrj  public:
301a9fa9459Szrj   struct Range
302a9fa9459Szrj   {
RangeRange303a9fa9459Szrj     Range(unsigned int a_shndx, off_t a_start, off_t a_end)
304a9fa9459Szrj       : shndx(a_shndx), start(a_start), end(a_end)
305a9fa9459Szrj     { }
306a9fa9459Szrj 
307a9fa9459Szrj     unsigned int shndx;
308a9fa9459Szrj     off_t start;
309a9fa9459Szrj     off_t end;
310a9fa9459Szrj   };
311a9fa9459Szrj 
Dwarf_range_list()312a9fa9459Szrj   Dwarf_range_list()
313a9fa9459Szrj     : range_list_()
314a9fa9459Szrj   { }
315a9fa9459Szrj 
316a9fa9459Szrj   void
add(unsigned int shndx,off_t start,off_t end)317a9fa9459Szrj   add(unsigned int shndx, off_t start, off_t end)
318a9fa9459Szrj   { this->range_list_.push_back(Range(shndx, start, end)); }
319a9fa9459Szrj 
320a9fa9459Szrj   size_t
size()321a9fa9459Szrj   size() const
322a9fa9459Szrj   { return this->range_list_.size(); }
323a9fa9459Szrj 
324a9fa9459Szrj   const Range&
325a9fa9459Szrj   operator[](off_t i) const
326a9fa9459Szrj   { return this->range_list_[i]; }
327a9fa9459Szrj 
328a9fa9459Szrj  private:
329a9fa9459Szrj   std::vector<Range> range_list_;
330a9fa9459Szrj };
331a9fa9459Szrj 
332a9fa9459Szrj // This class is used to read the ranges table from the
333a9fa9459Szrj // .debug_ranges section of the object file.
334a9fa9459Szrj 
335a9fa9459Szrj class Dwarf_ranges_table
336a9fa9459Szrj {
337a9fa9459Szrj  public:
Dwarf_ranges_table(Dwarf_info_reader * dwinfo)338a9fa9459Szrj   Dwarf_ranges_table(Dwarf_info_reader* dwinfo)
339a9fa9459Szrj     : dwinfo_(dwinfo), ranges_shndx_(0), ranges_buffer_(NULL),
340a9fa9459Szrj       ranges_buffer_end_(NULL), owns_ranges_buffer_(false),
341a9fa9459Szrj       ranges_reloc_mapper_(NULL), reloc_type_(0), output_section_offset_(0)
342a9fa9459Szrj   { }
343a9fa9459Szrj 
~Dwarf_ranges_table()344a9fa9459Szrj   ~Dwarf_ranges_table()
345a9fa9459Szrj   {
346a9fa9459Szrj     if (this->owns_ranges_buffer_ && this->ranges_buffer_ != NULL)
347a9fa9459Szrj       delete[] this->ranges_buffer_;
348a9fa9459Szrj     if (this->ranges_reloc_mapper_ != NULL)
349a9fa9459Szrj       delete this->ranges_reloc_mapper_;
350a9fa9459Szrj   }
351a9fa9459Szrj 
352a9fa9459Szrj   // Read the ranges table from an object file.
353a9fa9459Szrj   bool
354a9fa9459Szrj   read_ranges_table(Relobj* object,
355a9fa9459Szrj 		    const unsigned char* symtab,
356a9fa9459Szrj 		    off_t symtab_size,
357a9fa9459Szrj 		    unsigned int ranges_shndx);
358a9fa9459Szrj 
359a9fa9459Szrj   // Read the range table from an object file.
360a9fa9459Szrj   Dwarf_range_list*
361a9fa9459Szrj   read_range_list(Relobj* object,
362a9fa9459Szrj 		  const unsigned char* symtab,
363a9fa9459Szrj 		  off_t symtab_size,
364a9fa9459Szrj 		  unsigned int address_size,
365a9fa9459Szrj 		  unsigned int ranges_shndx,
366a9fa9459Szrj 		  off_t ranges_offset);
367a9fa9459Szrj 
368a9fa9459Szrj   // Look for a relocation at offset OFF in the range table,
369a9fa9459Szrj   // and return the section index and offset of the target.
370a9fa9459Szrj   unsigned int
371a9fa9459Szrj   lookup_reloc(off_t off, off_t* target_off);
372a9fa9459Szrj 
373a9fa9459Szrj  private:
374a9fa9459Szrj   // The Dwarf_info_reader, for reading data.
375a9fa9459Szrj   Dwarf_info_reader* dwinfo_;
376a9fa9459Szrj   // The section index of the ranges table.
377a9fa9459Szrj   unsigned int ranges_shndx_;
378a9fa9459Szrj   // The buffer containing the .debug_ranges section.
379a9fa9459Szrj   const unsigned char* ranges_buffer_;
380a9fa9459Szrj   const unsigned char* ranges_buffer_end_;
381a9fa9459Szrj   // True if this object owns the buffer and needs to delete it.
382a9fa9459Szrj   bool owns_ranges_buffer_;
383a9fa9459Szrj   // Relocation mapper for the .debug_ranges section.
384a9fa9459Szrj   Elf_reloc_mapper* ranges_reloc_mapper_;
385a9fa9459Szrj   // Type of the relocation section (SHT_REL or SHT_RELA).
386a9fa9459Szrj   unsigned int reloc_type_;
387a9fa9459Szrj   // For incremental update links, this will hold the offset of the
388a9fa9459Szrj   // input section within the output section.  Offsets read from
389a9fa9459Szrj   // relocated data will be relative to the output section, and need
390a9fa9459Szrj   // to be corrected before reading data from the input section.
391a9fa9459Szrj   uint64_t output_section_offset_;
392a9fa9459Szrj };
393a9fa9459Szrj 
394a9fa9459Szrj // This class is used to read the pubnames and pubtypes tables from the
395a9fa9459Szrj // .debug_pubnames and .debug_pubtypes sections of the object file.
396a9fa9459Szrj 
397a9fa9459Szrj class Dwarf_pubnames_table
398a9fa9459Szrj {
399a9fa9459Szrj  public:
Dwarf_pubnames_table(Dwarf_info_reader * dwinfo,bool is_pubtypes)400a9fa9459Szrj   Dwarf_pubnames_table(Dwarf_info_reader* dwinfo, bool is_pubtypes)
401a9fa9459Szrj     : dwinfo_(dwinfo), buffer_(NULL), buffer_end_(NULL), owns_buffer_(false),
402a9fa9459Szrj       offset_size_(0), pinfo_(NULL), end_of_table_(NULL),
403a9fa9459Szrj       is_pubtypes_(is_pubtypes), is_gnu_style_(false),
404a9fa9459Szrj       unit_length_(0), cu_offset_(0)
405a9fa9459Szrj   { }
406a9fa9459Szrj 
~Dwarf_pubnames_table()407a9fa9459Szrj   ~Dwarf_pubnames_table()
408a9fa9459Szrj   {
409a9fa9459Szrj     if (this->owns_buffer_ && this->buffer_ != NULL)
410a9fa9459Szrj       delete[] this->buffer_;
411a9fa9459Szrj   }
412a9fa9459Szrj 
413a9fa9459Szrj   // Read the pubnames section from the object file, using the symbol
414a9fa9459Szrj   // table for relocating it.
415a9fa9459Szrj   bool
416a9fa9459Szrj   read_section(Relobj* object, const unsigned char* symbol_table,
417a9fa9459Szrj                off_t symtab_size);
418a9fa9459Szrj 
419a9fa9459Szrj   // Read the header for the set at OFFSET.
420a9fa9459Szrj   bool
421a9fa9459Szrj   read_header(off_t offset);
422a9fa9459Szrj 
423a9fa9459Szrj   // Return the offset to the cu within the info or types section.
424a9fa9459Szrj   off_t
cu_offset()425a9fa9459Szrj   cu_offset()
426a9fa9459Szrj   { return this->cu_offset_; }
427a9fa9459Szrj 
428a9fa9459Szrj   // Return the size of this subsection of the table.  The unit length
429a9fa9459Szrj   // doesn't include the size of its own field.
430a9fa9459Szrj   off_t
subsection_size()431a9fa9459Szrj   subsection_size()
432a9fa9459Szrj   { return this->unit_length_; }
433a9fa9459Szrj 
434a9fa9459Szrj   // Read the next name from the set.  If the pubname table is gnu-style,
435a9fa9459Szrj   // FLAG_BYTE is set to the high-byte of a gdb_index version 7 cu_index.
436a9fa9459Szrj   const char*
437a9fa9459Szrj   next_name(uint8_t* flag_byte);
438a9fa9459Szrj 
439a9fa9459Szrj  private:
440a9fa9459Szrj   // The Dwarf_info_reader, for reading data.
441a9fa9459Szrj   Dwarf_info_reader* dwinfo_;
442a9fa9459Szrj   // The buffer containing the .debug_ranges section.
443a9fa9459Szrj   const unsigned char* buffer_;
444a9fa9459Szrj   const unsigned char* buffer_end_;
445a9fa9459Szrj   // True if this object owns the buffer and needs to delete it.
446a9fa9459Szrj   bool owns_buffer_;
447a9fa9459Szrj   // The size of a DWARF offset for the current set.
448a9fa9459Szrj   unsigned int offset_size_;
449a9fa9459Szrj   // The current position within the buffer.
450a9fa9459Szrj   const unsigned char* pinfo_;
451a9fa9459Szrj   // The end of the current pubnames table.
452a9fa9459Szrj   const unsigned char* end_of_table_;
453a9fa9459Szrj   // TRUE if this is a .debug_pubtypes section.
454a9fa9459Szrj   bool is_pubtypes_;
455a9fa9459Szrj   // Gnu-style pubnames table. This style has an extra flag byte between the
456a9fa9459Szrj   // offset and the name, and is used for generating version 7 of gdb-index.
457a9fa9459Szrj   bool is_gnu_style_;
458a9fa9459Szrj   // Fields read from the header.
459a9fa9459Szrj   uint64_t unit_length_;
460a9fa9459Szrj   off_t cu_offset_;
461a9fa9459Szrj 
462a9fa9459Szrj   // Track relocations for this table so we can find the CUs that
463a9fa9459Szrj   // correspond to the subsections.
464a9fa9459Szrj   Elf_reloc_mapper* reloc_mapper_;
465a9fa9459Szrj   // Type of the relocation section (SHT_REL or SHT_RELA).
466a9fa9459Szrj   unsigned int reloc_type_;
467a9fa9459Szrj };
468a9fa9459Szrj 
469a9fa9459Szrj // This class represents a DWARF Debug Info Entry (DIE).
470a9fa9459Szrj 
471a9fa9459Szrj class Dwarf_die
472a9fa9459Szrj {
473a9fa9459Szrj  public:
474a9fa9459Szrj   // An attribute value.
475a9fa9459Szrj   struct Attribute_value
476a9fa9459Szrj   {
477a9fa9459Szrj     unsigned int attr;
478a9fa9459Szrj     unsigned int form;
479a9fa9459Szrj     union
480a9fa9459Szrj     {
481a9fa9459Szrj       int64_t intval;
482a9fa9459Szrj       uint64_t uintval;
483a9fa9459Szrj       const char* stringval;
484a9fa9459Szrj       const unsigned char* blockval;
485a9fa9459Szrj       off_t refval;
486a9fa9459Szrj     } val;
487a9fa9459Szrj     union
488a9fa9459Szrj     {
489a9fa9459Szrj       // Section index for reference forms.
490a9fa9459Szrj       unsigned int shndx;
491a9fa9459Szrj       // Block length for block forms.
492a9fa9459Szrj       unsigned int blocklen;
493a9fa9459Szrj       // Attribute offset for DW_FORM_strp.
494a9fa9459Szrj       unsigned int attr_off;
495a9fa9459Szrj     } aux;
496a9fa9459Szrj   };
497a9fa9459Szrj 
498a9fa9459Szrj   // A list of attribute values.
499a9fa9459Szrj   typedef std::vector<Attribute_value> Attributes;
500a9fa9459Szrj 
501a9fa9459Szrj   Dwarf_die(Dwarf_info_reader* dwinfo,
502a9fa9459Szrj 	    off_t die_offset,
503a9fa9459Szrj 	    Dwarf_die* parent);
504a9fa9459Szrj 
505a9fa9459Szrj   // Return the DWARF tag for this DIE.
506a9fa9459Szrj   unsigned int
tag()507a9fa9459Szrj   tag() const
508a9fa9459Szrj   {
509a9fa9459Szrj     if (this->abbrev_code_ == NULL)
510a9fa9459Szrj       return 0;
511a9fa9459Szrj     return this->abbrev_code_->tag;
512a9fa9459Szrj   }
513a9fa9459Szrj 
514a9fa9459Szrj   // Return true if this DIE has children.
515a9fa9459Szrj   bool
has_children()516a9fa9459Szrj   has_children() const
517a9fa9459Szrj   {
518a9fa9459Szrj     gold_assert(this->abbrev_code_ != NULL);
519a9fa9459Szrj     return this->abbrev_code_->has_children;
520a9fa9459Szrj   }
521a9fa9459Szrj 
522a9fa9459Szrj   // Return true if this DIE has a sibling attribute.
523a9fa9459Szrj   bool
has_sibling_attribute()524a9fa9459Szrj   has_sibling_attribute() const
525a9fa9459Szrj   {
526a9fa9459Szrj     gold_assert(this->abbrev_code_ != NULL);
527a9fa9459Szrj     return this->abbrev_code_->has_sibling_attribute;
528a9fa9459Szrj   }
529a9fa9459Szrj 
530a9fa9459Szrj   // Return the value of attribute ATTR.
531a9fa9459Szrj   const Attribute_value*
532a9fa9459Szrj   attribute(unsigned int attr);
533a9fa9459Szrj 
534a9fa9459Szrj   // Return the value of the DW_AT_name attribute.
535a9fa9459Szrj   const char*
name()536a9fa9459Szrj   name()
537a9fa9459Szrj   {
538a9fa9459Szrj     if (this->name_ == NULL)
539a9fa9459Szrj       this->set_name();
540a9fa9459Szrj     return this->name_;
541a9fa9459Szrj   }
542a9fa9459Szrj 
543a9fa9459Szrj   // Return the value of the DW_AT_linkage_name
544a9fa9459Szrj   // or DW_AT_MIPS_linkage_name attribute.
545a9fa9459Szrj   const char*
linkage_name()546a9fa9459Szrj   linkage_name()
547a9fa9459Szrj   {
548a9fa9459Szrj     if (this->linkage_name_ == NULL)
549a9fa9459Szrj       this->set_linkage_name();
550a9fa9459Szrj     return this->linkage_name_;
551a9fa9459Szrj   }
552a9fa9459Szrj 
553a9fa9459Szrj   // Return the value of the DW_AT_specification attribute.
554a9fa9459Szrj   off_t
specification()555a9fa9459Szrj   specification()
556a9fa9459Szrj   {
557a9fa9459Szrj     if (!this->attributes_read_)
558a9fa9459Szrj       this->read_attributes();
559a9fa9459Szrj     return this->specification_;
560a9fa9459Szrj   }
561a9fa9459Szrj 
562a9fa9459Szrj   // Return the value of the DW_AT_abstract_origin attribute.
563a9fa9459Szrj   off_t
abstract_origin()564a9fa9459Szrj   abstract_origin()
565a9fa9459Szrj   {
566a9fa9459Szrj     if (!this->attributes_read_)
567a9fa9459Szrj       this->read_attributes();
568a9fa9459Szrj     return this->abstract_origin_;
569a9fa9459Szrj   }
570a9fa9459Szrj 
571a9fa9459Szrj   // Return the value of attribute ATTR as a string.
572a9fa9459Szrj   const char*
573a9fa9459Szrj   string_attribute(unsigned int attr);
574a9fa9459Szrj 
575a9fa9459Szrj   // Return the value of attribute ATTR as an integer.
576a9fa9459Szrj   int64_t
577a9fa9459Szrj   int_attribute(unsigned int attr);
578a9fa9459Szrj 
579a9fa9459Szrj   // Return the value of attribute ATTR as an unsigned integer.
580a9fa9459Szrj   uint64_t
581a9fa9459Szrj   uint_attribute(unsigned int attr);
582a9fa9459Szrj 
583a9fa9459Szrj   // Return the value of attribute ATTR as a reference.
584a9fa9459Szrj   off_t
585a9fa9459Szrj   ref_attribute(unsigned int attr, unsigned int* shndx);
586a9fa9459Szrj 
587a9fa9459Szrj   // Return the value of attribute ATTR as a address.
588a9fa9459Szrj   off_t
589a9fa9459Szrj   address_attribute(unsigned int attr, unsigned int* shndx);
590a9fa9459Szrj 
591a9fa9459Szrj   // Return the value of attribute ATTR as a flag.
592a9fa9459Szrj   bool
flag_attribute(unsigned int attr)593a9fa9459Szrj   flag_attribute(unsigned int attr)
594a9fa9459Szrj   { return this->int_attribute(attr) != 0; }
595a9fa9459Szrj 
596a9fa9459Szrj   // Return true if this DIE is a declaration.
597a9fa9459Szrj   bool
is_declaration()598a9fa9459Szrj   is_declaration()
599a9fa9459Szrj   { return this->flag_attribute(elfcpp::DW_AT_declaration); }
600a9fa9459Szrj 
601a9fa9459Szrj   // Return the parent of this DIE.
602a9fa9459Szrj   Dwarf_die*
parent()603a9fa9459Szrj   parent() const
604a9fa9459Szrj   { return this->parent_; }
605a9fa9459Szrj 
606a9fa9459Szrj   // Return the offset of this DIE.
607a9fa9459Szrj   off_t
offset()608a9fa9459Szrj   offset() const
609a9fa9459Szrj   { return this->die_offset_; }
610a9fa9459Szrj 
611a9fa9459Szrj   // Return the offset of this DIE's first child.
612a9fa9459Szrj   off_t
613a9fa9459Szrj   child_offset();
614a9fa9459Szrj 
615a9fa9459Szrj   // Set the offset of this DIE's next sibling.
616a9fa9459Szrj   void
set_sibling_offset(off_t sibling_offset)617a9fa9459Szrj   set_sibling_offset(off_t sibling_offset)
618a9fa9459Szrj   { this->sibling_offset_ = sibling_offset; }
619a9fa9459Szrj 
620a9fa9459Szrj   // Return the offset of this DIE's next sibling.
621a9fa9459Szrj   off_t
622a9fa9459Szrj   sibling_offset();
623a9fa9459Szrj 
624a9fa9459Szrj  private:
625a9fa9459Szrj   typedef Dwarf_abbrev_table::Abbrev_code Abbrev_code;
626a9fa9459Szrj 
627a9fa9459Szrj   // Read all the attributes of the DIE.
628a9fa9459Szrj   bool
629a9fa9459Szrj   read_attributes();
630a9fa9459Szrj 
631a9fa9459Szrj   // Set the name of the DIE if present.
632a9fa9459Szrj   void
633a9fa9459Szrj   set_name();
634a9fa9459Szrj 
635a9fa9459Szrj   // Set the linkage name if present.
636a9fa9459Szrj   void
637a9fa9459Szrj   set_linkage_name();
638a9fa9459Szrj 
639a9fa9459Szrj   // Skip all the attributes of the DIE and return the offset
640a9fa9459Szrj   // of the next DIE.
641a9fa9459Szrj   off_t
642a9fa9459Szrj   skip_attributes();
643a9fa9459Szrj 
644a9fa9459Szrj   // The Dwarf_info_reader, for reading attributes.
645a9fa9459Szrj   Dwarf_info_reader* dwinfo_;
646a9fa9459Szrj   // The parent of this DIE.
647a9fa9459Szrj   Dwarf_die* parent_;
648a9fa9459Szrj   // Offset of this DIE within its compilation unit.
649a9fa9459Szrj   off_t die_offset_;
650a9fa9459Szrj   // Offset of the first attribute, relative to the beginning of the DIE.
651a9fa9459Szrj   off_t attr_offset_;
652a9fa9459Szrj   // Offset of the first child, relative to the compilation unit.
653a9fa9459Szrj   off_t child_offset_;
654a9fa9459Szrj   // Offset of the next sibling, relative to the compilation unit.
655a9fa9459Szrj   off_t sibling_offset_;
656a9fa9459Szrj   // The abbreviation table entry.
657a9fa9459Szrj   const Abbrev_code* abbrev_code_;
658a9fa9459Szrj   // The list of attributes.
659a9fa9459Szrj   Attributes attributes_;
660a9fa9459Szrj   // True if the attributes have been read.
661a9fa9459Szrj   bool attributes_read_;
662a9fa9459Szrj   // The following fields hold common attributes to avoid a linear
663a9fa9459Szrj   // search through the attribute list.
664a9fa9459Szrj   // The DIE name (DW_AT_name).
665a9fa9459Szrj   const char* name_;
666a9fa9459Szrj   // Offset of the name in the string table (for DW_FORM_strp).
667a9fa9459Szrj   off_t name_off_;
668a9fa9459Szrj   // The linkage name (DW_AT_linkage_name or DW_AT_MIPS_linkage_name).
669a9fa9459Szrj   const char* linkage_name_;
670a9fa9459Szrj   // Offset of the linkage name in the string table (for DW_FORM_strp).
671a9fa9459Szrj   off_t linkage_name_off_;
672a9fa9459Szrj   // Section index of the string table (for DW_FORM_strp).
673a9fa9459Szrj   unsigned int string_shndx_;
674a9fa9459Szrj   // The value of a DW_AT_specification attribute.
675a9fa9459Szrj   off_t specification_;
676a9fa9459Szrj   // The value of a DW_AT_abstract_origin attribute.
677a9fa9459Szrj   off_t abstract_origin_;
678a9fa9459Szrj };
679a9fa9459Szrj 
680a9fa9459Szrj // This class is used to read the debug info from the .debug_info
681a9fa9459Szrj // or .debug_types sections.  This is a base class that implements
682a9fa9459Szrj // the generic parsing of the compilation unit header and DIE
683a9fa9459Szrj // structure.  The parse() method parses the entire section, and
684a9fa9459Szrj // calls the various visit_xxx() methods for each header.  Clients
685a9fa9459Szrj // should derive a new class from this one and implement the
686a9fa9459Szrj // visit_compilation_unit() and visit_type_unit() functions.
687a9fa9459Szrj 
688a9fa9459Szrj class Dwarf_info_reader
689a9fa9459Szrj {
690a9fa9459Szrj  public:
Dwarf_info_reader(bool is_type_unit,Relobj * object,const unsigned char * symtab,off_t symtab_size,unsigned int shndx,unsigned int reloc_shndx,unsigned int reloc_type)691a9fa9459Szrj   Dwarf_info_reader(bool is_type_unit,
692a9fa9459Szrj 		    Relobj* object,
693a9fa9459Szrj 		    const unsigned char* symtab,
694a9fa9459Szrj 		    off_t symtab_size,
695a9fa9459Szrj 		    unsigned int shndx,
696a9fa9459Szrj 		    unsigned int reloc_shndx,
697a9fa9459Szrj 		    unsigned int reloc_type)
698a9fa9459Szrj     : is_type_unit_(is_type_unit), object_(object), symtab_(symtab),
699a9fa9459Szrj       symtab_size_(symtab_size), shndx_(shndx), reloc_shndx_(reloc_shndx),
700a9fa9459Szrj       reloc_type_(reloc_type), abbrev_shndx_(0), string_shndx_(0),
701a9fa9459Szrj       buffer_(NULL), buffer_end_(NULL), cu_offset_(0), cu_length_(0),
702a9fa9459Szrj       offset_size_(0), address_size_(0), cu_version_(0),
703a9fa9459Szrj       abbrev_table_(), ranges_table_(this),
704a9fa9459Szrj       reloc_mapper_(NULL), string_buffer_(NULL), string_buffer_end_(NULL),
705a9fa9459Szrj       owns_string_buffer_(false), string_output_section_offset_(0)
706a9fa9459Szrj   { }
707a9fa9459Szrj 
708a9fa9459Szrj   virtual
~Dwarf_info_reader()709a9fa9459Szrj   ~Dwarf_info_reader()
710a9fa9459Szrj   {
711a9fa9459Szrj     if (this->reloc_mapper_ != NULL)
712a9fa9459Szrj       delete this->reloc_mapper_;
713a9fa9459Szrj     if (this->owns_string_buffer_ && this->string_buffer_ != NULL)
714a9fa9459Szrj       delete[] this->string_buffer_;
715a9fa9459Szrj   }
716a9fa9459Szrj 
717a9fa9459Szrj   // Begin parsing the debug info.  This calls visit_compilation_unit()
718a9fa9459Szrj   // or visit_type_unit() for each compilation or type unit found in the
719a9fa9459Szrj   // section, and visit_die() for each top-level DIE.
720a9fa9459Szrj   void
721a9fa9459Szrj   parse();
722a9fa9459Szrj 
723a9fa9459Szrj   // Return the abbrev code entry for a CODE.
724a9fa9459Szrj   const Dwarf_abbrev_table::Abbrev_code*
get_abbrev(unsigned int code)725a9fa9459Szrj   get_abbrev(unsigned int code)
726a9fa9459Szrj   { return this->abbrev_table_.get_abbrev(code); }
727a9fa9459Szrj 
728a9fa9459Szrj   // Return a pointer to the DWARF info buffer at OFFSET.
729a9fa9459Szrj   const unsigned char*
buffer_at_offset(off_t offset)730a9fa9459Szrj   buffer_at_offset(off_t offset) const
731a9fa9459Szrj   {
732a9fa9459Szrj     const unsigned char* p = this->buffer_ + this->cu_offset_ + offset;
733a9fa9459Szrj     if (this->check_buffer(p + 1))
734a9fa9459Szrj       return p;
735a9fa9459Szrj     return NULL;
736a9fa9459Szrj   }
737a9fa9459Szrj 
738a9fa9459Szrj   // Read a possibly unaligned integer of SIZE.
739a9fa9459Szrj   template <int valsize>
740a9fa9459Szrj   inline typename elfcpp::Valtype_base<valsize>::Valtype
741a9fa9459Szrj   read_from_pointer(const unsigned char* source);
742a9fa9459Szrj 
743a9fa9459Szrj   // Read a possibly unaligned integer of SIZE.  Update SOURCE after read.
744a9fa9459Szrj   template <int valsize>
745a9fa9459Szrj   inline typename elfcpp::Valtype_base<valsize>::Valtype
746a9fa9459Szrj   read_from_pointer(const unsigned char** source);
747a9fa9459Szrj 
748a9fa9459Szrj   // Look for a relocation at offset ATTR_OFF in the dwarf info,
749a9fa9459Szrj   // and return the section index and offset of the target.
750a9fa9459Szrj   unsigned int
751a9fa9459Szrj   lookup_reloc(off_t attr_off, off_t* target_off);
752a9fa9459Szrj 
753a9fa9459Szrj   // Return a string from the DWARF string table.
754a9fa9459Szrj   const char*
755a9fa9459Szrj   get_string(off_t str_off, unsigned int string_shndx);
756a9fa9459Szrj 
757a9fa9459Szrj   // Return the size of a DWARF offset.
758a9fa9459Szrj   unsigned int
offset_size()759a9fa9459Szrj   offset_size() const
760a9fa9459Szrj   { return this->offset_size_; }
761a9fa9459Szrj 
762a9fa9459Szrj   // Return the size of an address.
763a9fa9459Szrj   unsigned int
address_size()764a9fa9459Szrj   address_size() const
765a9fa9459Szrj   { return this->address_size_; }
766a9fa9459Szrj 
767a9fa9459Szrj   // Set the section index of the .debug_abbrev section.
768a9fa9459Szrj   // We use this if there are no relocations for the .debug_info section.
769a9fa9459Szrj   // If not set, the code parse() routine will search for the section by name.
770a9fa9459Szrj   void
set_abbrev_shndx(unsigned int abbrev_shndx)771a9fa9459Szrj   set_abbrev_shndx(unsigned int abbrev_shndx)
772a9fa9459Szrj   { this->abbrev_shndx_ = abbrev_shndx; }
773a9fa9459Szrj 
774a9fa9459Szrj   // Return a pointer to the object file's ELF symbol table.
775a9fa9459Szrj   const unsigned char*
symtab()776a9fa9459Szrj   symtab() const
777a9fa9459Szrj   { return this->symtab_; }
778a9fa9459Szrj 
779a9fa9459Szrj   // Return the size of the object file's ELF symbol table.
780a9fa9459Szrj   off_t
symtab_size()781a9fa9459Szrj   symtab_size() const
782a9fa9459Szrj   { return this->symtab_size_; }
783a9fa9459Szrj 
784a9fa9459Szrj   // Return the offset of the current compilation unit.
785a9fa9459Szrj   off_t
cu_offset()786a9fa9459Szrj   cu_offset() const
787a9fa9459Szrj   { return this->cu_offset_; }
788a9fa9459Szrj 
789a9fa9459Szrj  protected:
790a9fa9459Szrj   // Begin parsing the debug info.  This calls visit_compilation_unit()
791a9fa9459Szrj   // or visit_type_unit() for each compilation or type unit found in the
792a9fa9459Szrj   // section, and visit_die() for each top-level DIE.
793a9fa9459Szrj   template<bool big_endian>
794a9fa9459Szrj   void
795a9fa9459Szrj   do_parse();
796a9fa9459Szrj 
797a9fa9459Szrj   // The following methods are hooks that are meant to be implemented
798a9fa9459Szrj   // by a derived class.  A default, do-nothing, implementation of
799a9fa9459Szrj   // each is provided for this base class.
800a9fa9459Szrj 
801a9fa9459Szrj   // Visit a compilation unit.
802a9fa9459Szrj   virtual void
803a9fa9459Szrj   visit_compilation_unit(off_t cu_offset, off_t cu_length, Dwarf_die* root_die);
804a9fa9459Szrj 
805a9fa9459Szrj   // Visit a type unit.
806a9fa9459Szrj   virtual void
807a9fa9459Szrj   visit_type_unit(off_t tu_offset, off_t tu_length, off_t type_offset,
808a9fa9459Szrj 		  uint64_t signature, Dwarf_die* root_die);
809a9fa9459Szrj 
810a9fa9459Szrj   // Read the range table.
811a9fa9459Szrj   Dwarf_range_list*
read_range_list(unsigned int ranges_shndx,off_t ranges_offset)812a9fa9459Szrj   read_range_list(unsigned int ranges_shndx, off_t ranges_offset)
813a9fa9459Szrj   {
814a9fa9459Szrj     return this->ranges_table_.read_range_list(this->object_,
815a9fa9459Szrj 					       this->symtab_,
816a9fa9459Szrj 					       this->symtab_size_,
817a9fa9459Szrj 					       this->address_size_,
818a9fa9459Szrj 					       ranges_shndx,
819a9fa9459Szrj 					       ranges_offset);
820a9fa9459Szrj   }
821a9fa9459Szrj 
822a9fa9459Szrj   // Return the object.
823a9fa9459Szrj   Relobj*
object()824a9fa9459Szrj   object() const
825a9fa9459Szrj   { return this->object_; }
826a9fa9459Szrj 
827a9fa9459Szrj   // Checkpoint the relocation tracker.
828a9fa9459Szrj   uint64_t
get_reloc_checkpoint()829a9fa9459Szrj   get_reloc_checkpoint() const
830a9fa9459Szrj   { return this->reloc_mapper_->checkpoint(); }
831a9fa9459Szrj 
832a9fa9459Szrj   // Reset the relocation tracker to the CHECKPOINT.
833a9fa9459Szrj   void
reset_relocs(uint64_t checkpoint)834a9fa9459Szrj   reset_relocs(uint64_t checkpoint)
835a9fa9459Szrj   { this->reloc_mapper_->reset(checkpoint); }
836a9fa9459Szrj 
837a9fa9459Szrj  private:
838a9fa9459Szrj   // Print a warning about a corrupt debug section.
839a9fa9459Szrj   void
840a9fa9459Szrj   warn_corrupt_debug_section() const;
841a9fa9459Szrj 
842a9fa9459Szrj   // Check that P is within the bounds of the current section.
843a9fa9459Szrj   bool
check_buffer(const unsigned char * p)844a9fa9459Szrj   check_buffer(const unsigned char* p) const
845a9fa9459Szrj   {
846a9fa9459Szrj     if (p > this->buffer_ + this->cu_offset_ + this->cu_length_)
847a9fa9459Szrj       {
848a9fa9459Szrj 	this->warn_corrupt_debug_section();
849a9fa9459Szrj 	return false;
850a9fa9459Szrj       }
851a9fa9459Szrj     return true;
852a9fa9459Szrj   }
853a9fa9459Szrj 
854a9fa9459Szrj   // Read the DWARF string table.
855a9fa9459Szrj   bool
read_string_table(unsigned int string_shndx)856a9fa9459Szrj   read_string_table(unsigned int string_shndx)
857a9fa9459Szrj   {
858a9fa9459Szrj     // If we've already read this string table, return immediately.
859a9fa9459Szrj     if (this->string_shndx_ > 0 && this->string_shndx_ == string_shndx)
860a9fa9459Szrj       return true;
861a9fa9459Szrj     if (string_shndx == 0 && this->string_shndx_ > 0)
862a9fa9459Szrj       return true;
863a9fa9459Szrj     return this->do_read_string_table(string_shndx);
864a9fa9459Szrj   }
865a9fa9459Szrj 
866a9fa9459Szrj   bool
867a9fa9459Szrj   do_read_string_table(unsigned int string_shndx);
868a9fa9459Szrj 
869a9fa9459Szrj   // True if this is a type unit; false for a compilation unit.
870a9fa9459Szrj   bool is_type_unit_;
871a9fa9459Szrj   // The object containing the .debug_info or .debug_types input section.
872a9fa9459Szrj   Relobj* object_;
873a9fa9459Szrj   // The ELF symbol table.
874a9fa9459Szrj   const unsigned char* symtab_;
875a9fa9459Szrj   // The size of the ELF symbol table.
876a9fa9459Szrj   off_t symtab_size_;
877a9fa9459Szrj   // Index of the .debug_info or .debug_types section.
878a9fa9459Szrj   unsigned int shndx_;
879a9fa9459Szrj   // Index of the relocation section.
880a9fa9459Szrj   unsigned int reloc_shndx_;
881a9fa9459Szrj   // Type of the relocation section (SHT_REL or SHT_RELA).
882a9fa9459Szrj   unsigned int reloc_type_;
883a9fa9459Szrj   // Index of the .debug_abbrev section (0 if not known).
884a9fa9459Szrj   unsigned int abbrev_shndx_;
885a9fa9459Szrj   // Index of the .debug_str section.
886a9fa9459Szrj   unsigned int string_shndx_;
887a9fa9459Szrj   // The buffer for the debug info.
888a9fa9459Szrj   const unsigned char* buffer_;
889a9fa9459Szrj   const unsigned char* buffer_end_;
890a9fa9459Szrj   // Offset of the current compilation unit.
891a9fa9459Szrj   off_t cu_offset_;
892a9fa9459Szrj   // Length of the current compilation unit.
893a9fa9459Szrj   off_t cu_length_;
894a9fa9459Szrj   // Size of a DWARF offset for the current compilation unit.
895a9fa9459Szrj   unsigned int offset_size_;
896a9fa9459Szrj   // Size of an address for the target architecture.
897a9fa9459Szrj   unsigned int address_size_;
898a9fa9459Szrj   // Compilation unit version number.
899a9fa9459Szrj   unsigned int cu_version_;
900a9fa9459Szrj   // Abbreviations table for current compilation unit.
901a9fa9459Szrj   Dwarf_abbrev_table abbrev_table_;
902a9fa9459Szrj   // Ranges table for the current compilation unit.
903a9fa9459Szrj   Dwarf_ranges_table ranges_table_;
904a9fa9459Szrj   // Relocation mapper for the section.
905a9fa9459Szrj   Elf_reloc_mapper* reloc_mapper_;
906a9fa9459Szrj   // The buffer for the debug string table.
907a9fa9459Szrj   const char* string_buffer_;
908a9fa9459Szrj   const char* string_buffer_end_;
909a9fa9459Szrj   // True if this object owns the buffer and needs to delete it.
910a9fa9459Szrj   bool owns_string_buffer_;
911a9fa9459Szrj   // For incremental update links, this will hold the offset of the
912a9fa9459Szrj   // input .debug_str section within the output section.  Offsets read
913a9fa9459Szrj   // from relocated data will be relative to the output section, and need
914a9fa9459Szrj   // to be corrected before reading data from the input section.
915a9fa9459Szrj   uint64_t string_output_section_offset_;
916a9fa9459Szrj };
917a9fa9459Szrj 
918a9fa9459Szrj // We can't do better than to keep the offsets in a sorted vector.
919a9fa9459Szrj // Here, offset is the key, and file_num/line_num is the value.
920a9fa9459Szrj struct Offset_to_lineno_entry
921a9fa9459Szrj {
922a9fa9459Szrj   off_t offset;
923a9fa9459Szrj   int header_num;  // which file-list to use (i.e. which .o file are we in)
924a9fa9459Szrj   // A pointer into files_.
925a9fa9459Szrj   unsigned int file_num : sizeof(int) * CHAR_BIT - 1;
926a9fa9459Szrj   // True if this was the last entry for the current offset, meaning
927a9fa9459Szrj   // it's the line that actually applies.
928a9fa9459Szrj   unsigned int last_line_for_offset : 1;
929a9fa9459Szrj   // The line number in the source file.  -1 to indicate end-of-function.
930a9fa9459Szrj   int line_num;
931a9fa9459Szrj 
932a9fa9459Szrj   // This sorts by offsets first, and then puts the correct line to
933a9fa9459Szrj   // report for a given offset at the beginning of the run of equal
934a9fa9459Szrj   // offsets (so that asking for 1 line gives the best answer).  This
935a9fa9459Szrj   // is not a total ordering.
936a9fa9459Szrj   bool operator<(const Offset_to_lineno_entry& that) const
937a9fa9459Szrj   {
938a9fa9459Szrj     if (this->offset != that.offset)
939a9fa9459Szrj       return this->offset < that.offset;
940a9fa9459Szrj     // Note the '>' which makes this sort 'true' first.
941a9fa9459Szrj     return this->last_line_for_offset > that.last_line_for_offset;
942a9fa9459Szrj   }
943a9fa9459Szrj };
944a9fa9459Szrj 
945a9fa9459Szrj // This class is used to read the line information from the debugging
946a9fa9459Szrj // section of an object file.
947a9fa9459Szrj 
948a9fa9459Szrj class Dwarf_line_info
949a9fa9459Szrj {
950a9fa9459Szrj  public:
Dwarf_line_info()951a9fa9459Szrj   Dwarf_line_info()
952a9fa9459Szrj   { }
953a9fa9459Szrj 
954a9fa9459Szrj   virtual
~Dwarf_line_info()955a9fa9459Szrj   ~Dwarf_line_info()
956a9fa9459Szrj   { }
957a9fa9459Szrj 
958a9fa9459Szrj   // Given a section number and an offset, returns the associated
959a9fa9459Szrj   // file and line-number, as a string: "file:lineno".  If unable
960a9fa9459Szrj   // to do the mapping, returns the empty string.  You must call
961a9fa9459Szrj   // read_line_mappings() before calling this function.  If
962a9fa9459Szrj   // 'other_lines' is non-NULL, fills that in with other line
963a9fa9459Szrj   // numbers assigned to the same offset.
964a9fa9459Szrj   std::string
addr2line(unsigned int shndx,off_t offset,std::vector<std::string> * other_lines)965a9fa9459Szrj   addr2line(unsigned int shndx, off_t offset,
966a9fa9459Szrj             std::vector<std::string>* other_lines)
967a9fa9459Szrj   { return this->do_addr2line(shndx, offset, other_lines); }
968a9fa9459Szrj 
969a9fa9459Szrj   // A helper function for a single addr2line lookup.  It also keeps a
970a9fa9459Szrj   // cache of the last CACHE_SIZE Dwarf_line_info objects it created;
971a9fa9459Szrj   // set to 0 not to cache at all.  The larger CACHE_SIZE is, the more
972a9fa9459Szrj   // chance this routine won't have to re-create a Dwarf_line_info
973a9fa9459Szrj   // object for its addr2line computation; such creations are slow.
974a9fa9459Szrj   // NOTE: Not thread-safe, so only call from one thread at a time.
975a9fa9459Szrj   static std::string
976a9fa9459Szrj   one_addr2line(Object* object, unsigned int shndx, off_t offset,
977a9fa9459Szrj                 size_t cache_size, std::vector<std::string>* other_lines);
978a9fa9459Szrj 
979a9fa9459Szrj   // This reclaims all the memory that one_addr2line may have cached.
980a9fa9459Szrj   // Use this when you know you will not be calling one_addr2line again.
981a9fa9459Szrj   static void
982a9fa9459Szrj   clear_addr2line_cache();
983a9fa9459Szrj 
984a9fa9459Szrj  private:
985a9fa9459Szrj   virtual std::string
986a9fa9459Szrj   do_addr2line(unsigned int shndx, off_t offset,
987a9fa9459Szrj                std::vector<std::string>* other_lines) = 0;
988a9fa9459Szrj };
989a9fa9459Szrj 
990a9fa9459Szrj template<int size, bool big_endian>
991a9fa9459Szrj class Sized_dwarf_line_info : public Dwarf_line_info
992a9fa9459Szrj {
993a9fa9459Szrj  public:
994a9fa9459Szrj   // Initializes a .debug_line reader for a given object file.
995a9fa9459Szrj   // If SHNDX is specified and non-negative, only read the debug
996a9fa9459Szrj   // information that pertains to the specified section.
997a9fa9459Szrj   Sized_dwarf_line_info(Object* object, unsigned int read_shndx = -1U);
998a9fa9459Szrj 
999a9fa9459Szrj   virtual
~Sized_dwarf_line_info()1000a9fa9459Szrj   ~Sized_dwarf_line_info()
1001a9fa9459Szrj   {
1002a9fa9459Szrj     if (this->buffer_start_ != NULL)
1003a9fa9459Szrj       delete[] this->buffer_start_;
1004a9fa9459Szrj   }
1005a9fa9459Szrj 
1006a9fa9459Szrj  private:
1007a9fa9459Szrj   std::string
1008a9fa9459Szrj   do_addr2line(unsigned int shndx, off_t offset,
1009a9fa9459Szrj                std::vector<std::string>* other_lines);
1010a9fa9459Szrj 
1011a9fa9459Szrj   // Formats a file and line number to a string like "dirname/filename:lineno".
1012a9fa9459Szrj   std::string
1013a9fa9459Szrj   format_file_lineno(const Offset_to_lineno_entry& lineno) const;
1014a9fa9459Szrj 
1015a9fa9459Szrj   // Start processing line info, and populates the offset_map_.
1016a9fa9459Szrj   // If SHNDX is non-negative, only store debug information that
1017a9fa9459Szrj   // pertains to the specified section.
1018a9fa9459Szrj   void
1019a9fa9459Szrj   read_line_mappings(unsigned int shndx);
1020a9fa9459Szrj 
1021a9fa9459Szrj   // Reads the relocation section associated with .debug_line and
1022a9fa9459Szrj   // stores relocation information in reloc_map_.
1023a9fa9459Szrj   void
1024a9fa9459Szrj   read_relocs();
1025a9fa9459Szrj 
1026a9fa9459Szrj   // Reads the DWARF2/3 header for this line info.  Each takes as input
1027a9fa9459Szrj   // a starting buffer position, and returns the ending position.
1028a9fa9459Szrj   const unsigned char*
1029a9fa9459Szrj   read_header_prolog(const unsigned char* lineptr);
1030a9fa9459Szrj 
1031a9fa9459Szrj   const unsigned char*
1032a9fa9459Szrj   read_header_tables(const unsigned char* lineptr);
1033a9fa9459Szrj 
1034a9fa9459Szrj   // Reads the DWARF2/3 line information.  If shndx is non-negative,
1035a9fa9459Szrj   // discard all line information that doesn't pertain to the given
1036a9fa9459Szrj   // section.
1037a9fa9459Szrj   const unsigned char*
1038a9fa9459Szrj   read_lines(const unsigned char* lineptr, unsigned int shndx);
1039a9fa9459Szrj 
1040a9fa9459Szrj   // Process a single line info opcode at START using the state
1041a9fa9459Szrj   // machine at LSM.  Return true if we should define a line using the
1042a9fa9459Szrj   // current state of the line state machine.  Place the length of the
1043a9fa9459Szrj   // opcode in LEN.
1044a9fa9459Szrj   bool
1045a9fa9459Szrj   process_one_opcode(const unsigned char* start,
1046a9fa9459Szrj                      struct LineStateMachine* lsm, size_t* len);
1047a9fa9459Szrj 
1048a9fa9459Szrj   // Some parts of processing differ depending on whether the input
1049a9fa9459Szrj   // was a .o file or not.
1050a9fa9459Szrj   bool input_is_relobj();
1051a9fa9459Szrj 
1052a9fa9459Szrj   // If we saw anything amiss while parsing, we set this to false.
1053a9fa9459Szrj   // Then addr2line will always fail (rather than return possibly-
1054a9fa9459Szrj   // corrupt data).
1055a9fa9459Szrj   bool data_valid_;
1056a9fa9459Szrj 
1057a9fa9459Szrj   // A DWARF2/3 line info header.  This is not the same size as in the
1058a9fa9459Szrj   // actual file, as the one in the file may have a 32 bit or 64 bit
1059a9fa9459Szrj   // lengths.
1060a9fa9459Szrj 
1061a9fa9459Szrj   struct Dwarf_line_infoHeader
1062a9fa9459Szrj   {
1063a9fa9459Szrj     off_t total_length;
1064a9fa9459Szrj     int version;
1065a9fa9459Szrj     off_t prologue_length;
1066*8c87cab6Szrj     int min_insn_length; // insn stands for instruction
1067*8c87cab6Szrj     int max_ops_per_insn; // Added in DWARF-4.
1068a9fa9459Szrj     bool default_is_stmt; // stmt stands for statement
1069a9fa9459Szrj     signed char line_base;
1070a9fa9459Szrj     int line_range;
1071a9fa9459Szrj     unsigned char opcode_base;
1072a9fa9459Szrj     std::vector<unsigned char> std_opcode_lengths;
1073a9fa9459Szrj     int offset_size;
1074a9fa9459Szrj   } header_;
1075a9fa9459Szrj 
1076a9fa9459Szrj   // buffer is the buffer for our line info, starting at exactly where
1077a9fa9459Szrj   // the line info to read is.
1078a9fa9459Szrj   const unsigned char* buffer_;
1079a9fa9459Szrj   const unsigned char* buffer_end_;
1080a9fa9459Szrj   // If the buffer was allocated temporarily, and therefore must be
1081a9fa9459Szrj   // deallocated in the dtor, this contains a pointer to the start
1082a9fa9459Szrj   // of the buffer.
1083a9fa9459Szrj   const unsigned char* buffer_start_;
1084a9fa9459Szrj 
1085a9fa9459Szrj   // This has relocations that point into buffer.
1086a9fa9459Szrj   Sized_elf_reloc_mapper<size, big_endian>* reloc_mapper_;
1087a9fa9459Szrj   // The type of the reloc section in track_relocs_--SHT_REL or SHT_RELA.
1088a9fa9459Szrj   unsigned int track_relocs_type_;
1089a9fa9459Szrj 
1090a9fa9459Szrj   // This is used to figure out what section to apply a relocation to.
1091a9fa9459Szrj   const unsigned char* symtab_buffer_;
1092a9fa9459Szrj   section_size_type symtab_buffer_size_;
1093a9fa9459Szrj 
1094a9fa9459Szrj   // Holds the directories and files as we see them.  We have an array
1095a9fa9459Szrj   // of directory-lists, one for each .o file we're reading (usually
1096a9fa9459Szrj   // there will just be one, but there may be more if input is a .so).
1097a9fa9459Szrj   std::vector<std::vector<std::string> > directories_;
1098a9fa9459Szrj   // The first part is an index into directories_, the second the filename.
1099a9fa9459Szrj   std::vector<std::vector< std::pair<int, std::string> > > files_;
1100a9fa9459Szrj 
1101a9fa9459Szrj   // An index into the current directories_ and files_ vectors.
1102a9fa9459Szrj   int current_header_index_;
1103a9fa9459Szrj 
1104a9fa9459Szrj   // A sorted map from offset of the relocation target to the shndx
1105a9fa9459Szrj   // and addend for the relocation.
1106a9fa9459Szrj   typedef std::map<off_t, std::pair<unsigned int, off_t> >
1107a9fa9459Szrj   Reloc_map;
1108a9fa9459Szrj   Reloc_map reloc_map_;
1109a9fa9459Szrj 
1110a9fa9459Szrj   // We have a vector of offset->lineno entries for every input section.
1111a9fa9459Szrj   typedef Unordered_map<unsigned int, std::vector<Offset_to_lineno_entry> >
1112a9fa9459Szrj   Lineno_map;
1113a9fa9459Szrj 
1114a9fa9459Szrj   Lineno_map line_number_map_;
1115a9fa9459Szrj };
1116a9fa9459Szrj 
1117a9fa9459Szrj } // End namespace gold.
1118a9fa9459Szrj 
1119a9fa9459Szrj #endif // !defined(GOLD_DWARF_READER_H)
1120