1/* Low-level DWARF 2 reading code
2
3   Copyright (C) 1994-2023 Free Software Foundation, Inc.
4
5   Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
6   Inc.  with support from Florida State University (under contract
7   with the Ada Joint Program Office), and Silicon Graphics, Inc.
8   Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
9   based on Fred Fish's (Cygnus Support) implementation of DWARF 1
10   support.
11
12   This file is part of GDB.
13
14   This program is free software; you can redistribute it and/or modify
15   it under the terms of the GNU General Public License as published by
16   the Free Software Foundation; either version 3 of the License, or
17   (at your option) any later version.
18
19   This program is distributed in the hope that it will be useful,
20   but WITHOUT ANY WARRANTY; without even the implied warranty of
21   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22   GNU General Public License for more details.
23
24   You should have received a copy of the GNU General Public License
25   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
26
27#include "defs.h"
28#include "dwarf2/leb.h"
29
30ULONGEST
31read_unsigned_leb128 (bfd *abfd, const gdb_byte *buf,
32			  unsigned int *bytes_read_ptr)
33{
34  ULONGEST result;
35  unsigned int num_read;
36  int shift;
37  unsigned char byte;
38
39  result = 0;
40  shift = 0;
41  num_read = 0;
42  while (1)
43    {
44      byte = bfd_get_8 (abfd, buf);
45      buf++;
46      num_read++;
47      result |= ((ULONGEST) (byte & 127) << shift);
48      if ((byte & 128) == 0)
49	{
50	  break;
51	}
52      shift += 7;
53    }
54  *bytes_read_ptr = num_read;
55  return result;
56}
57
58LONGEST
59read_signed_leb128 (bfd *abfd, const gdb_byte *buf,
60		    unsigned int *bytes_read_ptr)
61{
62  ULONGEST result;
63  int shift, num_read;
64  unsigned char byte;
65
66  result = 0;
67  shift = 0;
68  num_read = 0;
69  while (1)
70    {
71      byte = bfd_get_8 (abfd, buf);
72      buf++;
73      num_read++;
74      result |= ((ULONGEST) (byte & 127) << shift);
75      shift += 7;
76      if ((byte & 128) == 0)
77	{
78	  break;
79	}
80    }
81  if ((shift < 8 * sizeof (result)) && (byte & 0x40))
82    result |= -(((ULONGEST) 1) << shift);
83  *bytes_read_ptr = num_read;
84  return result;
85}
86
87/* See leb.h.  */
88
89LONGEST
90read_initial_length (bfd *abfd, const gdb_byte *buf, unsigned int *bytes_read,
91		     bool handle_nonstd)
92{
93  LONGEST length = bfd_get_32 (abfd, buf);
94
95  if (length == 0xffffffff)
96    {
97      length = bfd_get_64 (abfd, buf + 4);
98      *bytes_read = 12;
99    }
100  else if (handle_nonstd && length == 0)
101    {
102      /* Handle the (non-standard) 64-bit DWARF2 format used by IRIX.  */
103      length = bfd_get_64 (abfd, buf);
104      *bytes_read = 8;
105    }
106  else
107    {
108      *bytes_read = 4;
109    }
110
111  return length;
112}
113
114/* See leb.h.  */
115
116LONGEST
117read_offset (bfd *abfd, const gdb_byte *buf, unsigned int offset_size)
118{
119  LONGEST retval = 0;
120
121  switch (offset_size)
122    {
123    case 4:
124      retval = bfd_get_32 (abfd, buf);
125      break;
126    case 8:
127      retval = bfd_get_64 (abfd, buf);
128      break;
129    default:
130      internal_error (_("read_offset_1: bad switch [in module %s]"),
131		      bfd_get_filename (abfd));
132    }
133
134  return retval;
135}
136