From: Mark Wielaard Date: Wed, 1 Jul 2026 11:03:07 +0000 (+0200) Subject: libdw: Add Dwarf_Type (plain, dwo, gnu_lto) support for dwarf_begin X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e55252e432cc254c4ad4ac632f68c36b4514e598;p=thirdparty%2Felfutils.git libdw: Add Dwarf_Type (plain, dwo, gnu_lto) support for dwarf_begin This introduces three new libdw functions dwarf_begin_type, dwarf_begin_elf_type and dwarf_type. When a file contained multiple types of DWARF, plain DWARF, DWO or GNU_LTO, dwarf_begin and dwarf_begin_elf would use the plain DWARF when available, otherwise use the DWO sections and finally the GNU_LTO sections to construct a Dwarf handle. This meant that if a file contained multiple types you would only be able to get one. And you couldn't explicitly say you only wanted a Dwarf handle for a specific type. Also you had no clear way of determining which type of Dwarf handle you got. The new dwarf_begin_type and dwarf_begin_elf_type allow explicitly specifying a specific type of DWARF you want. And the dwarf_type function will return the actual type of DWARF you got. * libdw/libdw.h (Dwarf_Type): New enum. (dwarf_begin_type): New function declaration. (dwarf_begin_elf_type): Likewise. (dwarf_get_type): Likewise. * libdw/libdw.map (ELFUTILS_0.196): New section with new function symbols based on ELFUTILS_0.194_EXPERIMENTAL. * libdw/libdwP.h (enum dwarf_type): Removed. (struct Dwarf): Make Dwarf_Type type. (INTDECL): dwarf_begin_elf_type, dwarf_begin_type, dwarf_get_type. * libdw/dwarf_begin.c (dwarf_begin): Rename to and make a wrapper around... (dwarf_begin_type): ... this new function. * libdw/dwarf_begin_elf.c (scn_dwarf_type): Return a Dwarf_Type. (check_section): Use Dwarf_Type instead of enum dwarf_type. (global_read): Add requested_type argument. Split in DWARF_T_AUTO case and specific type case. (scngrp_read): Likewise. (dwarf_begin_elf): Rename to and make a wrapper around.., (dwarf_begin_elf_type): ... this new function. (dwarf_get_type): New function. * tests/Makefile.am (check_PROGRAMS): Add dwarf-type. (TESTS): Add run-dwarf-type.sh. (EXTRA_DIST): Likewise. (dwarf_type_LDADD): New. * tests/dwarf-type.c: New test. * tests/run-dwarf-type.sh: New test wrapper. https://sourceware.org/bugzilla/show_bug.cgi?id=28573 Signed-off-by: Mark Wielaard Two remaining issues: - Maybe we want a dedicated DWP type? Currently DWARF_T_DWO covers both single DWO and DWP/multi-DWO types. But this might not be a detail "real" users care about (only possibly useful for eu-dwp). - Currently seeing a .debug_dwp section always assumes it is a dwo/dwp file, but it could be a plain DWARF file with a DWP reference. Need to actually inspect the .debug_dwp section to see which it is. --- diff --git a/libdw/dwarf_begin.c b/libdw/dwarf_begin.c index 19d16e5c..fbf1b0f0 100644 --- a/libdw/dwarf_begin.c +++ b/libdw/dwarf_begin.c @@ -1,5 +1,6 @@ /* Create descriptor from file descriptor for processing file. Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. + Copyright (C) 2026 Mark J. Wielaard This file is part of elfutils. Written by Ulrich Drepper , 2002. @@ -39,7 +40,7 @@ Dwarf * -dwarf_begin (int fd, Dwarf_Cmd cmd) +dwarf_begin_type (int fd, Dwarf_Cmd cmd, Dwarf_Type type) { Elf *elf; Elf_Cmd elfcmd; @@ -85,7 +86,7 @@ dwarf_begin (int fd, Dwarf_Cmd cmd) else { /* Do the real work now that we have an ELF descriptor. */ - result = INTUSE(dwarf_begin_elf) (elf, cmd, NULL); + result = INTUSE(dwarf_begin_elf_type) (elf, cmd, type, NULL); /* If this failed, free the resources. */ if (result == NULL) @@ -96,4 +97,11 @@ dwarf_begin (int fd, Dwarf_Cmd cmd) return result; } +INTDEF(dwarf_begin_type) + +Dwarf * +dwarf_begin (int fd, Dwarf_Cmd cmd) +{ + return INTUSE(dwarf_begin_type) (fd, cmd, DWARF_T_AUTO); +} INTDEF(dwarf_begin) diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c index 7b58ad2e..5586ed66 100644 --- a/libdw/dwarf_begin_elf.c +++ b/libdw/dwarf_begin_elf.c @@ -1,6 +1,6 @@ /* Create descriptor from ELF descriptor for processing file. Copyright (C) 2002-2011, 2014, 2015, 2017, 2018 Red Hat, Inc. - Copyright (C) 2023, Mark J. Wielaard + Copyright (C) 2023, 2026 Mark J. Wielaard This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -99,37 +99,37 @@ static const enum string_section_index scn_to_string_section_idx[IDX_last] = [IDX_gnu_debugaltlink] = STR_SCN_IDX_last }; -static enum dwarf_type +static Dwarf_Type scn_dwarf_type (Dwarf *result, size_t shstrndx, Elf_Scn *scn) { GElf_Shdr shdr_mem; GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); if (shdr == NULL) - return TYPE_UNKNOWN; + return DWARF_T_AUTO; const char *scnname = elf_strptr (result->elf, shstrndx, shdr->sh_name); if (scnname != NULL) { if (startswith (scnname, ".gnu.debuglto_.debug")) - return TYPE_GNU_LTO; + return DWARF_T_GNU_LTO; else if (strcmp (scnname, ".debug_cu_index") == 0 || strcmp (scnname, ".debug_tu_index") == 0 || strcmp (scnname, ".debug_dwp") == 0 || strcmp (scnname, ".zdebug_cu_index") == 0 || strcmp (scnname, ".zdebug_tu_index") == 0 || strcmp (scnname, ".zdebug_dwp") == 0) - return TYPE_DWO; + return DWARF_T_DWO; else if (startswith (scnname, ".debug_") || startswith (scnname, ".zdebug_")) { size_t len = strlen (scnname); if (strcmp (scnname + len - 4, ".dwo") == 0) - return TYPE_DWO; + return DWARF_T_DWO; else - return TYPE_PLAIN; + return DWARF_T_PLAIN; } } - return TYPE_UNKNOWN; + return DWARF_T_AUTO; } static Dwarf * check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp) @@ -186,11 +186,11 @@ check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp) { /* .debug_cu_index and .debug_tu_index don't have a .dwo suffix, but they are for DWO. */ - if (result->type != TYPE_DWO + if (result->type != DWARF_T_DWO && (cnt == IDX_debug_cu_index || cnt == IDX_debug_tu_index)) continue; bool need_dot_dwo = - (result->type == TYPE_DWO + (result->type == DWARF_T_DWO && cnt != IDX_debug_cu_index && cnt != IDX_debug_tu_index); size_t dbglen = strlen (dwarf_scnnames[cnt]); @@ -217,7 +217,7 @@ check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp) && startswith (scnname, ".gnu.debuglto_") && strcmp (&scnname[14], dwarf_scnnames[cnt]) == 0) { - if (result->type == TYPE_GNU_LTO) + if (result->type == DWARF_T_GNU_LTO) break; } } @@ -482,17 +482,44 @@ valid_p (Dwarf *result) static Dwarf * -global_read (Dwarf *result, Elf *elf, size_t shstrndx) +global_read (Dwarf *result, Elf *elf, size_t shstrndx, + Dwarf_Type requested_type) { Elf_Scn *scn = NULL; - /* First check the type (PLAIN, DWO, LTO) we are looking for. We - prefer PLAIN if available over DWO, over LTO. */ - while ((scn = elf_nextscn (elf, scn)) != NULL && result->type != TYPE_PLAIN) + if (requested_type == DWARF_T_AUTO) { - enum dwarf_type type = scn_dwarf_type (result, shstrndx, scn); - if (type > result->type) - result->type = type; + /* First check the type (PLAIN, DWO, LTO) we are looking for. We + prefer PLAIN if available over DWO, over LTO. */ + while ((scn = elf_nextscn (elf, scn)) != NULL + && result->type != DWARF_T_PLAIN) + { + Dwarf_Type type = scn_dwarf_type (result, shstrndx, scn); + if (type > result->type) + result->type = type; + } + } + else + { + /* Check there is at least one section of the requested type. */ + bool found = false; + while ((scn = elf_nextscn (elf, scn)) != NULL && !found) + { + Dwarf_Type type = scn_dwarf_type (result, shstrndx, scn); + if (type == requested_type) + found = true; + } + + if (!found) + { + /* Requested type not available. */ + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_NO_DWARF); + free (result); + return NULL; + } + + result->type = requested_type; } scn = NULL; @@ -504,7 +531,8 @@ global_read (Dwarf *result, Elf *elf, size_t shstrndx) static Dwarf * -scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, Elf_Scn *scngrp) +scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, + Dwarf_Type requested_type, Elf_Scn *scngrp) { GElf_Shdr shdr_mem; GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem); @@ -541,24 +569,58 @@ scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, Elf_Scn *scngrp) Elf32_Word *scnidx = (Elf32_Word *) data->d_buf; size_t cnt; - /* First check the type (PLAIN, DWO, LTO) we are looking for. We - prefer PLAIN if available over DWO, over LTO. */ - for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt) + if (requested_type == DWARF_T_AUTO) { - Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]); - if (scn == NULL) + /* First check the type (PLAIN, DWO, LTO) we are looking for. We + prefer PLAIN if available over DWO, over LTO. */ + for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt) { - /* A section group refers to a non-existing section. Should - never happen. */ + Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]); + if (scn == NULL) + { + /* A section group refers to a non-existing section. Should + never happen. */ + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_INVALID_ELF); + free (result); + return NULL; + } + + Dwarf_Type type = scn_dwarf_type (result, shstrndx, scn); + if (type > result->type) + result->type = type; + } + } + else + { + /* Check there is at least one section of the requested type. */ + bool found = false; + for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size && !found; ++cnt) + { + Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]); + if (scn == NULL) + { + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_INVALID_ELF); + free (result); + return NULL; + } + + Dwarf_Type type = scn_dwarf_type (result, shstrndx, scn); + if (type == requested_type) + found = true; + } + + if (!found) + { + /* Requested type not available. */ Dwarf_Sig8_Hash_free (&result->sig8_hash); - __libdw_seterrno (DWARF_E_INVALID_ELF); + __libdw_seterrno (DWARF_E_NO_DWARF); free (result); return NULL; } - enum dwarf_type type = scn_dwarf_type (result, shstrndx, scn); - if (type > result->type) - result->type = type; + result->type = requested_type; } for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size && result != NULL; ++cnt) @@ -575,7 +637,8 @@ scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, Elf_Scn *scngrp) Dwarf * -dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp) +dwarf_begin_elf_type (Elf *elf, Dwarf_Cmd cmd, Dwarf_Type type, + Elf_Scn *scngrp) { GElf_Ehdr *ehdr; GElf_Ehdr ehdr_mem; @@ -644,9 +707,9 @@ dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp) sections with the name are ignored. The DWARF specification does not really say this is allowed. */ if (scngrp == NULL) - return global_read (result, elf, shstrndx); + return global_read (result, elf, shstrndx, type); else - return scngrp_read (result, elf, shstrndx, scngrp); + return scngrp_read (result, elf, shstrndx, type, scngrp); } else if (cmd == DWARF_C_WRITE) { @@ -661,4 +724,22 @@ dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp) free (result); return NULL; } +INTDEF(dwarf_begin_elf_type) + +Dwarf * +dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp) +{ + return dwarf_begin_elf_type (elf, cmd, DWARF_T_AUTO, scngrp); +} INTDEF(dwarf_begin_elf) + +Dwarf_Type +dwarf_get_type (Dwarf *dwarf) +{ + if (dwarf == NULL) + return DWARF_T_AUTO; + + return dwarf->type; +} +INTDEF(dwarf_get_type) + diff --git a/libdw/libdw.h b/libdw/libdw.h index 9096f301..bcd76138 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -1,5 +1,6 @@ /* Interfaces for libdw. Copyright (C) 2002-2010, 2013, 2014, 2016, 2018 Red Hat, Inc. + Copyright (C) 2026 Mark J. Wielaard This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -43,6 +44,19 @@ typedef enum } Dwarf_Cmd; +/* DWARF type. Either plain DWARF, split DWARF DWOs or GNU LTO. When + used with dwarf_begin_type or dwarf_begin_elf_type DWARF_T_AUTO + tries to get PLAIN, DWO, GNU_LTO in that order. Enum values have a + numeric value indicating their priority in auto mode. */ +typedef enum + { + DWARF_T_AUTO = 0, /* Automatic selection (PLAIN > DWO > GNU_LTO). */ + DWARF_T_GNU_LTO = 16, /* GNU LTO (.gnu.debuglto_.debug_*). */ + DWARF_T_DWO = 32, /* Split DWARF (.debug_*.dwo). */ + DWARF_T_PLAIN = 64, /* Standard DWARF (.debug_*). */ + } +Dwarf_Type; + /* Callback results. */ enum @@ -234,12 +248,32 @@ typedef void (*__noreturn_attribute__ Dwarf_OOM) (void); extern "C" { #endif -/* Create a handle for a new debug session. */ +/* Create a handle for a new debug session. + Calls dwarf_begin_type (fildes, cmd, DWARF_T_AUTO). */ extern Dwarf *dwarf_begin (int fildes, Dwarf_Cmd cmd); -/* Create a handle for a new debug session for an ELF file. */ +/* Create a handle for a new debug session given a specific type. + When type is DWARF_T_AUTO will try to get PLAIN, DWO, GNU_LTO in + that order. Will return NULL if the requested type is not available + in the file. */ +extern Dwarf *dwarf_begin_type (int fildes, Dwarf_Cmd cmd, Dwarf_Type type); + +/* Create a handle for a new debug session for an ELF file. + Calls dwarf_begin_type (elf, cmd, DWARF_T_AUTO, scngrp). */ extern Dwarf *dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp); +/* Create a handle for a new debug session given a specific type. + When type is DWARF_T_AUTO will try to get PLAIN, DWO, GNU_LTO in + that order. Will return NULL if the requested type is not available + in the file. If scngrp isn't NULL it must be a SHT_GROUP section + and only sections in this group will be used. */ +extern Dwarf *dwarf_begin_elf_type (Elf *elf, Dwarf_Cmd cmd, Dwarf_Type type, + Elf_Scn *scngrp); + +/* Returns the DWARF type of the givn Dwarf descriptor. Return + DWARF_T_AUTO (zero) if the descriptor is NULL. */ +extern Dwarf_Type dwarf_get_type (Dwarf *dwarf); + /* Retrieve ELF descriptor used for DWARF access. */ extern Elf *dwarf_getelf (Dwarf *dwarf); diff --git a/libdw/libdw.map b/libdw/libdw.map index b45647e6..404b4c10 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -411,3 +411,10 @@ ELFUTILS_0.194_EXPERIMENTAL { global: dwflst_sample_getframes; } ELFUTILS_0.193_EXPERIMENTAL; + +ELFUTILS_0.196 { + global: + dwarf_begin_elf_type; + dwarf_begin_type; + dwarf_get_type; +} ELFUTILS_0.194_EXPERIMENTAL; diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 628777b0..8501337f 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -154,15 +154,6 @@ enum #include "dwarf_sig8_hash.h" -/* The type of Dwarf object, sorted by preference - (if there is a higher order type, we pick that one over the others). */ -enum dwarf_type - { - TYPE_UNKNOWN = 0, - TYPE_GNU_LTO = 16, - TYPE_DWO = 32, - TYPE_PLAIN = 64, - }; /* This is the structure representing the debugging state. */ struct Dwarf @@ -257,7 +248,7 @@ struct Dwarf /* Similar for addrx/constx, which will come from .debug_addr section. */ struct Dwarf_CU *fake_addr_cu; - enum dwarf_type type; + Dwarf_Type type; /* Supporting lock for internal memory handling. Ensures threads that have an entry in the mem_tails array are not disturbed by new threads doing @@ -486,6 +477,8 @@ INTDECL (dwarf_attr) INTDECL (dwarf_attr_integrate) INTDECL (dwarf_begin) INTDECL (dwarf_begin_elf) +INTDECL (dwarf_begin_elf_type) +INTDECL (dwarf_begin_type) INTDECL (dwarf_child) INTDECL (dwarf_cu_dwp_section_info) INTDECL (dwarf_default_lower_bound) @@ -508,6 +501,7 @@ INTDECL (dwarf_getaranges) INTDECL (dwarf_getlocation_die) INTDECL (dwarf_getsrcfiles) INTDECL (dwarf_getsrclines) +INTDECL (dwarf_get_type) INTDECL (dwarf_get_units) INTDECL (dwarf_hasattr) INTDECL (dwarf_haschildren) diff --git a/tests/Makefile.am b/tests/Makefile.am index d3ecd35b..4493f895 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -58,6 +58,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \ elfgetzdata elfputzdata zstrptr emptyfile vendorelf \ fillfile dwarf_default_lower_bound \ dwarf_language_lower_bound dwarf-die-addr-die \ + dwarf-type \ get-units-invalid get-units-split attr-integrate-skel \ all-dwarf-ranges unit-info next_cfi \ elfcopy addsections xlate_notes elfrdwrnop \ @@ -211,6 +212,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \ emptyfile vendorelf fillfile dwarf_default_lower_bound \ dwarf_language_lower_bound \ run-dwarf-die-addr-die.sh \ + run-dwarf-type.sh \ run-get-units-invalid.sh run-get-units-split.sh \ run-attr-integrate-skel.sh \ run-all-dwarf-ranges.sh run-unit-info.sh \ @@ -584,6 +586,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ testfile-bpf-reloc.expect.bz2 testfile-bpf-reloc.o.bz2 \ testfile-m68k-core.bz2 testfile-m68k.bz2 testfile-m68k-s.bz2 \ run-dwarf-die-addr-die.sh \ + run-dwarf-type.sh \ run-get-units-invalid.sh run-get-units-split.sh \ testfile-hello4.dwo.bz2 testfile-hello5.dwo.bz2 \ testfile-splitdwarf-4.bz2 testfile-splitdwarf-5.bz2 \ @@ -893,6 +896,7 @@ fillfile_LDADD = $(libelf) dwarf_default_lower_bound_LDADD = $(libdw) dwarf_language_lower_bound_LDADD = $(libdw) dwarf_die_addr_die_LDADD = $(libdw) +dwarf_type_LDADD = $(libdw) get_units_invalid_LDADD = $(libdw) get_units_split_LDADD = $(libdw) attr_integrate_skel_LDADD = $(libdw) diff --git a/tests/dwarf-type.c b/tests/dwarf-type.c new file mode 100644 index 00000000..9fff663e --- /dev/null +++ b/tests/dwarf-type.c @@ -0,0 +1,84 @@ +/* Test dwarf_begin_type and dwarf_get_type functionality. + Copyright (C) 2024 Red Hat, Inc. + This file is part of elfutils. + + This file 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. + + elfutils 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 . */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char * +type_name (Dwarf_Type type) +{ + switch (type) + { + case DWARF_T_AUTO: return "AUTO"; + case DWARF_T_PLAIN: return "PLAIN"; + case DWARF_T_DWO: return "DWO"; + case DWARF_T_GNU_LTO: return "GNU_LTO"; + default: return "UNKNOWN"; + } +} + +Dwarf_Type +name_type (const char *name) +{ + if (strcmp (name, "AUTO") == 0) + return DWARF_T_AUTO; + else if (strcmp (name, "PLAIN") == 0) + return DWARF_T_PLAIN; + else if (strcmp (name, "DWO") == 0) + return DWARF_T_DWO; + else if (strcmp (name, "GNU_LTO") == 0) + return DWARF_T_GNU_LTO; + else + { + printf ("Unknown type name: %s\n", name); + exit (1); + } +} + +int +main (int argc, char *argv[]) +{ + if (argc < 2) + { + fprintf (stderr, "Need and \n"); + return 1; + } + + const char *tname = argv[1]; + const char *file = argv[2]; + Dwarf_Type type = name_type (tname); + + int fd = open (file, O_RDONLY); + if (fd < 0) + { + printf ("Cannot open %s\n", file); + return 1; + } + + Dwarf *dbg = dwarf_begin_type (fd, DWARF_C_READ, type); + Dwarf_Type dwarf_type = dwarf_get_type (dbg); + printf ("%s: %s -> %s\n", file, type_name (type), type_name (dwarf_type)); + dwarf_end (dbg); + close (fd); + return 0; +} diff --git a/tests/run-dwarf-type.sh b/tests/run-dwarf-type.sh new file mode 100755 index 00000000..954d7851 --- /dev/null +++ b/tests/run-dwarf-type.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# Copyright (C) 2026 Mark J. Wielaard +# This file is part of elfutils. +# +# This file 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. +# +# elfutils 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 . + +. $srcdir/test-subr.sh + +# Test dwarf_begin_type and dwarf_get_type with fat LTO file +# (file with both PLAIN and GNU_LTO sections) +testfiles testfile-dwarf5-fat-lto.o + +testrun_compare ${abs_builddir}/dwarf-type AUTO testfile-dwarf5-fat-lto.o <<\EOF +testfile-dwarf5-fat-lto.o: AUTO -> PLAIN +EOF +testrun_compare ${abs_builddir}/dwarf-type PLAIN testfile-dwarf5-fat-lto.o <<\EOF +testfile-dwarf5-fat-lto.o: PLAIN -> PLAIN +EOF +testrun_compare ${abs_builddir}/dwarf-type DWO testfile-dwarf5-fat-lto.o <<\EOF +testfile-dwarf5-fat-lto.o: DWO -> AUTO +EOF +testrun_compare ${abs_builddir}/dwarf-type GNU_LTO testfile-dwarf5-fat-lto.o <<\EOF +testfile-dwarf5-fat-lto.o: GNU_LTO -> GNU_LTO +EOF + +# Test dwarf_begin_type and dwarf_get_type with DWO (only) file +testfiles testfile-hello5.dwo + +testrun_compare ${abs_builddir}/dwarf-type AUTO testfile-hello5.dwo <<\EOF +testfile-hello5.dwo: AUTO -> DWO +EOF +testrun_compare ${abs_builddir}/dwarf-type PLAIN testfile-hello5.dwo <<\EOF +testfile-hello5.dwo: PLAIN -> AUTO +EOF +testrun_compare ${abs_builddir}/dwarf-type DWO testfile-hello5.dwo <<\EOF +testfile-hello5.dwo: DWO -> DWO +EOF +testrun_compare ${abs_builddir}/dwarf-type GNU_LTO testfile-hello5.dwo <<\EOF +testfile-hello5.dwo: GNU_LTO -> AUTO +EOF + +exit 0