| /* Low-level DWARF 2 reading code |
| |
| Copyright (C) 1994-2021 Free Software Foundation, Inc. |
| |
| Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, |
| Inc. with support from Florida State University (under contract |
| with the Ada Joint Program Office), and Silicon Graphics, Inc. |
| Initial contribution by Brent Benson, Harris Computer Systems, Inc., |
| based on Fred Fish's (Cygnus Support) implementation of DWARF 1 |
| support. |
| |
| This file is part of GDB. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| |
| #include "defs.h" |
| #include "dwarf2/leb.h" |
| |
| ULONGEST |
| read_unsigned_leb128 (bfd *abfd, const gdb_byte *buf, |
| unsigned int *bytes_read_ptr) |
| { |
| ULONGEST result; |
| unsigned int num_read; |
| int shift; |
| unsigned char byte; |
| |
| result = 0; |
| shift = 0; |
| num_read = 0; |
| while (1) |
| { |
| byte = bfd_get_8 (abfd, buf); |
| buf++; |
| num_read++; |
| result |= ((ULONGEST) (byte & 127) << shift); |
| if ((byte & 128) == 0) |
| { |
| break; |
| } |
| shift += 7; |
| } |
| *bytes_read_ptr = num_read; |
| return result; |
| } |
| |
| LONGEST |
| read_signed_leb128 (bfd *abfd, const gdb_byte *buf, |
| unsigned int *bytes_read_ptr) |
| { |
| ULONGEST result; |
| int shift, num_read; |
| unsigned char byte; |
| |
| result = 0; |
| shift = 0; |
| num_read = 0; |
| while (1) |
| { |
| byte = bfd_get_8 (abfd, buf); |
| buf++; |
| num_read++; |
| result |= ((ULONGEST) (byte & 127) << shift); |
| shift += 7; |
| if ((byte & 128) == 0) |
| { |
| break; |
| } |
| } |
| if ((shift < 8 * sizeof (result)) && (byte & 0x40)) |
| result |= -(((ULONGEST) 1) << shift); |
| *bytes_read_ptr = num_read; |
| return result; |
| } |
| |
| /* See leb.h. */ |
| |
| LONGEST |
| read_initial_length (bfd *abfd, const gdb_byte *buf, unsigned int *bytes_read, |
| bool handle_nonstd) |
| { |
| LONGEST length = bfd_get_32 (abfd, buf); |
| |
| if (length == 0xffffffff) |
| { |
| length = bfd_get_64 (abfd, buf + 4); |
| *bytes_read = 12; |
| } |
| else if (handle_nonstd && length == 0) |
| { |
| /* Handle the (non-standard) 64-bit DWARF2 format used by IRIX. */ |
| length = bfd_get_64 (abfd, buf); |
| *bytes_read = 8; |
| } |
| else |
| { |
| *bytes_read = 4; |
| } |
| |
| return length; |
| } |
| |
| /* See leb.h. */ |
| |
| LONGEST |
| read_offset (bfd *abfd, const gdb_byte *buf, unsigned int offset_size) |
| { |
| LONGEST retval = 0; |
| |
| switch (offset_size) |
| { |
| case 4: |
| retval = bfd_get_32 (abfd, buf); |
| break; |
| case 8: |
| retval = bfd_get_64 (abfd, buf); |
| break; |
| default: |
| internal_error (__FILE__, __LINE__, |
| _("read_offset_1: bad switch [in module %s]"), |
| bfd_get_filename (abfd)); |
| } |
| |
| return retval; |
| } |