forked from openkylin/dwz
New upstream version 0.15
This commit is contained in:
parent
8435dca20b
commit
1785552f1c
|
@ -4,4 +4,5 @@
|
||||||
dwz
|
dwz
|
||||||
dwz.sum
|
dwz.sum
|
||||||
dwz.log
|
dwz.log
|
||||||
|
native.c
|
||||||
testsuite/dwz.tests/execs
|
testsuite/dwz.tests/execs
|
||||||
|
|
94
Makefile
94
Makefile
|
@ -3,25 +3,60 @@ VPATH = $(srcdir)
|
||||||
else
|
else
|
||||||
srcdir=$(shell pwd)
|
srcdir=$(shell pwd)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS = -O2 -g
|
CFLAGS = -O2 -g
|
||||||
DWZ_VERSION := $(shell cat $(srcdir)/VERSION)
|
DWZ_VERSION := $(shell cat $(srcdir)/VERSION)
|
||||||
override CFLAGS += -Wall -W -D_FILE_OFFSET_BITS=64 \
|
CFLAGS_VERSION = -DDWZ_VERSION='"$(DWZ_VERSION)"'
|
||||||
-DDWZ_VERSION='"$(DWZ_VERSION)"' $(shell cat $(srcdir)/COPYRIGHT_YEARS)
|
CFLAGS_COPYRIGHT = $(shell cat $(srcdir)/COPYRIGHT_YEARS)
|
||||||
|
CFLAGS_COMMON = -Wall -W -D_FILE_OFFSET_BITS=64
|
||||||
|
XXH_PROG = "\#define XXH_INLINE_ALL 1\n\#include <xxhash.h>\n"
|
||||||
|
XXH_INLINE_ALL_WORKS = $(shell printf $(XXH_PROG) \
|
||||||
|
| $(CC) -xc -c - -o /dev/null 2>/dev/null \
|
||||||
|
&& echo -n 1)
|
||||||
|
ifeq "$(XXH_INLINE_ALL_WORKS)" "1"
|
||||||
|
CFLAGS_COMMON += -DXXH_INLINE_ALL=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
override CFLAGS += $(CFLAGS_COMMON) $(CFLAGS_VERSION) $(CFLAGS_COPYRIGHT)
|
||||||
|
|
||||||
prefix = /usr
|
prefix = /usr
|
||||||
exec_prefix = $(prefix)
|
exec_prefix = $(prefix)
|
||||||
bindir = $(exec_prefix)/bin
|
bindir = $(exec_prefix)/bin
|
||||||
datarootdir = $(prefix)/share
|
datarootdir = $(prefix)/share
|
||||||
mandir = $(datarootdir)/man
|
mandir = $(datarootdir)/man
|
||||||
OBJECTS = dwz.o hashtab.o sha1.o dwarfnames.o
|
OBJECTS = args.o dwz.o hashtab.o pool.o sha1.o dwarfnames.o
|
||||||
|
LIBS=-lelf
|
||||||
|
ifneq "$(XXH_INLINE_ALL_WORKS)" "1"
|
||||||
|
LIBS += -lxxhash
|
||||||
|
endif
|
||||||
dwz: $(OBJECTS)
|
dwz: $(OBJECTS)
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lelf
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
args.o: native.o
|
||||||
|
args.o: CFLAGS_FOR_SOURCE = \
|
||||||
|
-DNATIVE_ENDIAN_VAL=$(NATIVE_ENDIAN_VAL) \
|
||||||
|
-DNATIVE_POINTER_SIZE=$(NATIVE_POINTER_SIZE)
|
||||||
|
NATIVE_ENDIAN=$(shell readelf -h native.o \
|
||||||
|
| grep Data \
|
||||||
|
| sed 's/.*, //;s/ endian//')
|
||||||
|
NATIVE_ENDIAN_LITTLE=$(findstring $(NATIVE_ENDIAN),$(findstring little,$(NATIVE_ENDIAN)))
|
||||||
|
NATIVE_ENDIAN_BIG=$(findstring $(NATIVE_ENDIAN),$(findstring big,$(NATIVE_ENDIAN)))
|
||||||
|
NATIVE_ENDIAN_VAL=$(if $(NATIVE_ENDIAN_LITTLE),ELFDATA2LSB,$(if $(NATIVE_ENDIAN_BIG),ELFDATA2MSB,ELFDATANONE))
|
||||||
|
NATIVE_POINTER_SIZE=$(shell readelf -wi native.o \
|
||||||
|
| grep "Pointer Size:" \
|
||||||
|
| sed 's/.*: *//')
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< $(CFLAGS_FOR_SOURCE)
|
||||||
install: dwz
|
install: dwz
|
||||||
install -D dwz $(DESTDIR)$(bindir)/dwz
|
install -D dwz $(DESTDIR)$(bindir)/dwz
|
||||||
install -D -m 644 $(srcdir)/dwz.1 $(DESTDIR)$(mandir)/man1/dwz.1
|
install -D -m 644 $(srcdir)/dwz.1 $(DESTDIR)$(mandir)/man1/dwz.1
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJECTS) *~ core* dwz $(TEST_EXECS) $(DWZ_TEST_SOURCES) \
|
rm -f $(OBJECTS) *~ core* dwz $(TEST_EXECS) $(DWZ_TEST_OBJECTS) \
|
||||||
dwz.log dwz.sum
|
dwz.log dwz.sum native.c native.o
|
||||||
rm -Rf testsuite-bin tmp.*
|
rm -Rf testsuite-bin tmp.*
|
||||||
|
native.c:
|
||||||
|
echo "int main (void) { return 0; }" > $@
|
||||||
|
native.o: native.c
|
||||||
|
$(CC) -o $@ $< -c -g
|
||||||
|
|
||||||
PWD:=$(shell pwd -P)
|
PWD:=$(shell pwd -P)
|
||||||
|
|
||||||
|
@ -33,7 +68,7 @@ TEST_EXECS_x86_64 = py-section-script dw2-skip-prologue \
|
||||||
TEST_EXECS = hello dwz-for-test min two-typedef start hello-gold-gdb-index \
|
TEST_EXECS = hello dwz-for-test min two-typedef start hello-gold-gdb-index \
|
||||||
start-gold hello-gnu-pubnames $(TEST_EXECS_DWARF_ASM) \
|
start-gold hello-gnu-pubnames $(TEST_EXECS_DWARF_ASM) \
|
||||||
$(TEST_EXECS_$(UNAME)) odr-struct odr-class odr-union odr-struct-ns \
|
$(TEST_EXECS_$(UNAME)) odr-struct odr-class odr-union odr-struct-ns \
|
||||||
odr-class-ns odr-union-ns odr-loc def-decl
|
odr-class-ns odr-union-ns odr-loc def-decl cycle
|
||||||
|
|
||||||
UNAME:=$(shell uname -p)
|
UNAME:=$(shell uname -p)
|
||||||
|
|
||||||
|
@ -50,15 +85,21 @@ dw2-skip-prologue:
|
||||||
py-section-script:
|
py-section-script:
|
||||||
$(CC) $(TEST_SRC)/py-section-script.s -o $@ -g || touch $@
|
$(CC) $(TEST_SRC)/py-section-script.s -o $@ -g || touch $@
|
||||||
|
|
||||||
DWZ_TEST_SOURCES := $(patsubst %.o,%-for-test.c,$(OBJECTS))
|
DWZ_TEST_OBJECTS := $(patsubst %.o,%-for-test.o,$(OBJECTS))
|
||||||
|
dwz-for-test: $(DWZ_TEST_OBJECTS)
|
||||||
%-for-test.c: %.c
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
sed 's/__GNUC__/NOT_DEFINED/' $< > $@
|
rm -f $(DWZ_TEST_OBJECTS)
|
||||||
|
args-for-test.o: CFLAGS_FOR_SOURCE = \
|
||||||
dwz-for-test: $(DWZ_TEST_SOURCES)
|
-DNATIVE_ENDIAN_VAL=$(NATIVE_ENDIAN_VAL) \
|
||||||
$(CC) $(DWZ_TEST_SOURCES) -O2 -g -lelf -o $@ -Wall -W -DDEVEL \
|
-DNATIVE_POINTER_SIZE=$(NATIVE_POINTER_SIZE)
|
||||||
-D_FILE_OFFSET_BITS=64 -DDWZ_VERSION='"for-test"' -I$(srcdir) \
|
$(DWZ_TEST_OBJECTS): %-for-test.o : %.c
|
||||||
$(shell cat $(srcdir)/COPYRIGHT_YEARS)
|
$(CC) $< -o $@ -c \
|
||||||
|
-DUSE_GNUC=0 -DDEVEL \
|
||||||
|
-O2 -g \
|
||||||
|
$(CFLAGS_COMMON) \
|
||||||
|
-DDWZ_VERSION='"for-test"' \
|
||||||
|
$(CFLAGS_COPYRIGHT) \
|
||||||
|
$(CFLAGS_FOR_SOURCE)
|
||||||
|
|
||||||
min:
|
min:
|
||||||
$(CC) $(TEST_SRC)/min.c $(TEST_SRC)/min-2.c -o $@ -g
|
$(CC) $(TEST_SRC)/min.c $(TEST_SRC)/min-2.c -o $@ -g
|
||||||
|
@ -96,11 +137,11 @@ $(TEMP_ASM_FILES): %-dw.S: $(TEST_SRC)/../lib/%.exp
|
||||||
export DEJAGNU=$(DEJAGNU); \
|
export DEJAGNU=$(DEJAGNU); \
|
||||||
runtest --tool=dwz -srcdir $(srcdir)/testsuite/ lib/$*.exp
|
runtest --tool=dwz -srcdir $(srcdir)/testsuite/ lib/$*.exp
|
||||||
|
|
||||||
$(filter-out no-multifile-prop, $(TEST_EXECS_DWARF_ASM)): %: %-dw.S
|
$(filter-out no-multifile-prop unavailable-dwarf-piece, $(TEST_EXECS_DWARF_ASM)): %: %-dw.S
|
||||||
$(CC) $(TEST_SRC)/main.c $< -o $@
|
$(CC) $(TEST_SRC)/main.c $< -o $@
|
||||||
|
|
||||||
# Fails to compile on riscv64: Error: non-constant .uleb128 is not supported.
|
# Fails to compile on riscv64: Error: non-constant .uleb128 is not supported.
|
||||||
no-multifile-prop: %: %-dw.S
|
no-multifile-prop unavailable-dwarf-piece: %: %-dw.S
|
||||||
$(CC) $(TEST_SRC)/main.c $< -o $@ || true
|
$(CC) $(TEST_SRC)/main.c $< -o $@ || true
|
||||||
|
|
||||||
odr-struct:
|
odr-struct:
|
||||||
|
@ -136,14 +177,25 @@ def-decl:
|
||||||
$(CXX) $(TEST_SRC)/decl.cc $(TEST_SRC)/def.cc $(TEST_SRC)/def2.cc \
|
$(CXX) $(TEST_SRC)/decl.cc $(TEST_SRC)/def.cc $(TEST_SRC)/def2.cc \
|
||||||
-I$(TEST_SRC) -o $@ -g
|
-I$(TEST_SRC) -o $@ -g
|
||||||
|
|
||||||
|
cycle:
|
||||||
|
$(CC) $(TEST_SRC)/cycle.c -o $@ -g
|
||||||
|
|
||||||
# On some systems we need to set and export DEJAGNU to suppress
|
# On some systems we need to set and export DEJAGNU to suppress
|
||||||
# WARNING: Couldn't find the global config file.
|
# WARNING: Couldn't find the global config file.
|
||||||
DEJAGNU ?= /dev/null
|
DEJAGNU ?= /dev/null
|
||||||
|
|
||||||
check: dwz $(TEST_EXECS)
|
VALGRIND_OPTIONS = -q --error-exitcode=99
|
||||||
|
|
||||||
|
check check-valgrind: dwz $(TEST_EXECS)
|
||||||
mkdir -p testsuite-bin
|
mkdir -p testsuite-bin
|
||||||
cd testsuite-bin; ln -sf $(PWD)/dwz .
|
cd testsuite-bin; \
|
||||||
|
if [ "$@" = "check" ]; then \
|
||||||
|
ln -sf $(PWD)/dwz .; \
|
||||||
|
else \
|
||||||
|
echo "valgrind $(VALGRIND_OPTIONS) $(PWD)/dwz \"\$$@\"" > dwz; \
|
||||||
|
chmod +x dwz; \
|
||||||
|
fi
|
||||||
export DEJAGNU=$(DEJAGNU); \
|
export DEJAGNU=$(DEJAGNU); \
|
||||||
export PATH=$(PWD)/testsuite-bin:$$PATH; export LC_ALL=C; \
|
export PATH=$(PWD)/testsuite-bin:$$PATH; export LC_ALL=C; \
|
||||||
runtest --tool=dwz -srcdir $(srcdir)/testsuite $(RUNTESTFLAGS)
|
runtest --tool=dwz -srcdir $(srcdir)/testsuite $(RUNTESTFLAGS)
|
||||||
rm -Rf testsuite-bin $(TEST_EXECS) $(DWZ_TEST_SOURCES)
|
rm -Rf testsuite-bin $(TEST_EXECS) $(DWZ_TEST_OBJECTS)
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
- Verify that copyright notices in source files are up-to-date.
|
||||||
|
- Update COPYRIGHT_YEARS using contrib/release/gen-copyright-years.sh.
|
||||||
|
Commit modifications if there are any.
|
||||||
|
- Run contrib/release/do-release.sh.
|
||||||
|
Use:
|
||||||
|
- --minor to do a minor update: $maj.$min -> $maj.$(($min + 1))
|
||||||
|
- --major to do a major update: $maj.$min -> $(($maj + 1)).0
|
||||||
|
This:
|
||||||
|
- adds a commit that updates the VERSION file,
|
||||||
|
- creates a signed annotated release tag for that commit, and
|
||||||
|
- pushes both the commit and the tag to the remote repository.
|
||||||
|
- Run contrib/release/upload-release.sh.
|
||||||
|
This creates and uploads two release tarballs.
|
||||||
|
- Write draft release announcement.
|
||||||
|
F.i. using template of
|
||||||
|
https://sourceware.org/ml/gdb-announce/2019/msg00001.html.
|
||||||
|
- Sent out draft release announcement to maintainers for review and
|
||||||
|
further contributions.
|
||||||
|
- Sent out release announcement. Sent to:
|
||||||
|
- Maintainers
|
||||||
|
- dwz@sourceware.org
|
||||||
|
- dwarf-discuss@lists.dwarfstd.org
|
||||||
|
- gcc@gcc.gnu.org
|
||||||
|
- gdb@sourceware.org
|
||||||
|
- lldb-dev@lists.llvm.org
|
||||||
|
- Update web page ( https://sourceware.org/dwz/ ):
|
||||||
|
- Add news item with hlink to release annoucement.
|
||||||
|
- Add entry in release list.
|
|
@ -0,0 +1,743 @@
|
||||||
|
/* Copyright (C) 2001-2021 Red Hat, Inc.
|
||||||
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
Copyright (C) 2019-2021 SUSE LLC.
|
||||||
|
Written by Jakub Jelinek <jakub@redhat.com>, 2012.
|
||||||
|
|
||||||
|
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 2, 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; see the file COPYING. If not, write to
|
||||||
|
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <error.h>
|
||||||
|
#include <gelf.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
|
||||||
|
#include "args.h"
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#if DEVEL
|
||||||
|
int tracing;
|
||||||
|
int ignore_size;
|
||||||
|
int ignore_locus;
|
||||||
|
int dump_checksum_p;
|
||||||
|
int dump_dies_p;
|
||||||
|
int dump_dups_p;
|
||||||
|
int dump_pus_p;
|
||||||
|
int verify_dups_p;
|
||||||
|
int verify_edge_freelist;
|
||||||
|
int stats_p;
|
||||||
|
int checksum_cycle_opt = 1;
|
||||||
|
int skip_producers_p;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int unoptimized_multifile;
|
||||||
|
int save_temps;
|
||||||
|
int verify_edges_p;
|
||||||
|
int dump_edges_p;
|
||||||
|
int partition_dups_opt;
|
||||||
|
int progress_p;
|
||||||
|
int progress_mem_p;
|
||||||
|
int import_opt_p = 1;
|
||||||
|
int force_p;
|
||||||
|
int max_forks = -1;
|
||||||
|
|
||||||
|
enum deduplication_mode deduplication_mode = dm_inter_cu;
|
||||||
|
|
||||||
|
int uni_lang_p = 0;
|
||||||
|
int gen_cu_p = 0;
|
||||||
|
|
||||||
|
enum die_count_methods die_count_method = estimate;
|
||||||
|
|
||||||
|
int odr = 0;
|
||||||
|
enum odr_mode odr_mode = ODR_LINK;
|
||||||
|
|
||||||
|
/* Filename if inter-file size optimization should be performed. */
|
||||||
|
const char *multifile;
|
||||||
|
|
||||||
|
/* Argument of -M option, i.e. preferred name that should be stored
|
||||||
|
into the .gnu_debugaltlink or .debug_sup section. */
|
||||||
|
const char *multifile_name;
|
||||||
|
|
||||||
|
/* True if -r option is present, i.e. .gnu_debugaltlink or .debug_sup section
|
||||||
|
should contain a filename relative to the directory in which
|
||||||
|
the particular file is present. */
|
||||||
|
bool multifile_relative;
|
||||||
|
|
||||||
|
/* Pointer size of multifile. */
|
||||||
|
int multifile_force_ptr_size;
|
||||||
|
/* Endianity of multifile. */
|
||||||
|
int multifile_force_endian;
|
||||||
|
|
||||||
|
/* True if DWARF 5 .debug_sup and DW_FORM_ref_sup4 / DW_FORM_strp_sup
|
||||||
|
should be used instead of the GNU extensions .gnu_debugaltlink
|
||||||
|
and DW_FORM_GNU_ref_alt / DW_FORM_GNU_strp_alt etc. */
|
||||||
|
bool dwarf_5;
|
||||||
|
|
||||||
|
/* True if -q option has been passed. */
|
||||||
|
bool quiet;
|
||||||
|
|
||||||
|
/* Number of DIEs, above which dwz retries processing
|
||||||
|
in low_mem mode (and give up on multifile optimizing
|
||||||
|
the file in question). */
|
||||||
|
unsigned int low_mem_die_limit = 10000000;
|
||||||
|
|
||||||
|
/* Number of DIEs, above which dwz gives up processing
|
||||||
|
input altogether. */
|
||||||
|
unsigned int max_die_limit = 50000000;
|
||||||
|
|
||||||
|
/* Phase of multifile handling. */
|
||||||
|
unsigned char multifile_mode;
|
||||||
|
|
||||||
|
static int die_count_method_parsed;
|
||||||
|
static int deduplication_mode_parsed;
|
||||||
|
static int odr_mode_parsed;
|
||||||
|
static int skip_producer_parsed;
|
||||||
|
|
||||||
|
/* Options for getopt_long. */
|
||||||
|
static struct option dwz_options[] =
|
||||||
|
{
|
||||||
|
{ "help", no_argument, 0, '?' },
|
||||||
|
{ "output", required_argument, 0, 'o' },
|
||||||
|
{ "multifile", required_argument, 0, 'm' },
|
||||||
|
{ "quiet", no_argument, 0, 'q' },
|
||||||
|
{ "hardlink", no_argument, 0, 'h' },
|
||||||
|
{ "low-mem-die-limit", required_argument, 0, 'l' },
|
||||||
|
{ "max-die-limit", required_argument, 0, 'L' },
|
||||||
|
{ "multifile-name", required_argument, 0, 'M' },
|
||||||
|
{ "relative", no_argument, 0, 'r' },
|
||||||
|
{ "version", no_argument, 0, 'v' },
|
||||||
|
{ "import-optimize",
|
||||||
|
no_argument, &import_opt_p, 1 },
|
||||||
|
{ "no-import-optimize",
|
||||||
|
no_argument, &import_opt_p, 0 },
|
||||||
|
{ "dwarf-5", no_argument, 0, '5' },
|
||||||
|
#if DEVEL
|
||||||
|
{ "devel-trace", no_argument, &tracing, 1 },
|
||||||
|
{ "devel-progress", no_argument, &progress_p, 1 },
|
||||||
|
{ "devel-progress-mem",no_argument, &progress_mem_p, 1 },
|
||||||
|
{ "devel-ignore-size", no_argument, &ignore_size, 1 },
|
||||||
|
{ "devel-ignore-locus",no_argument, &ignore_locus, 1 },
|
||||||
|
{ "devel-force", no_argument, &force_p, 1 },
|
||||||
|
{ "devel-save-temps", no_argument, &save_temps, 1 },
|
||||||
|
{ "devel-dump-checksum",
|
||||||
|
no_argument, &dump_checksum_p, 1 },
|
||||||
|
{ "devel-dump-dies", no_argument, &dump_dies_p, 1 },
|
||||||
|
{ "devel-dump-dups", no_argument, &dump_dups_p, 1 },
|
||||||
|
{ "devel-dump-pus", no_argument, &dump_pus_p, 1 },
|
||||||
|
{ "devel-unoptimized-multifile",
|
||||||
|
no_argument, &unoptimized_multifile, 1 },
|
||||||
|
{ "devel-verify-edges",no_argument, &verify_edges_p, 1 },
|
||||||
|
{ "devel-verify-dups", no_argument, &verify_dups_p, 1 },
|
||||||
|
{ "devel-dump-edges", no_argument, &dump_edges_p, 1 },
|
||||||
|
{ "devel-partition-dups-opt",
|
||||||
|
no_argument, &partition_dups_opt, 1 },
|
||||||
|
{ "devel-die-count-method",
|
||||||
|
required_argument, &die_count_method_parsed, 1 },
|
||||||
|
{ "devel-stats", no_argument, &stats_p, 1 },
|
||||||
|
{ "devel-deduplication-mode",
|
||||||
|
required_argument, &deduplication_mode_parsed, 1 },
|
||||||
|
{ "devel-uni-lang",
|
||||||
|
no_argument, &uni_lang_p, 1 },
|
||||||
|
{ "devel-no-uni-lang",
|
||||||
|
no_argument, &uni_lang_p, 0 },
|
||||||
|
{ "devel-gen-cu",
|
||||||
|
no_argument, &gen_cu_p, 1 },
|
||||||
|
{ "devel-no-gen-cu",
|
||||||
|
no_argument, &gen_cu_p, 0 },
|
||||||
|
{ "devel-checksum-cycle-opt",
|
||||||
|
no_argument, &checksum_cycle_opt, 1 },
|
||||||
|
{ "devel-no-checksum-cycle-opt",
|
||||||
|
no_argument, &checksum_cycle_opt, 0 },
|
||||||
|
{ "devel-skip-producer",
|
||||||
|
required_argument, &skip_producer_parsed, 1},
|
||||||
|
#endif
|
||||||
|
{ "odr", no_argument, &odr, 1 },
|
||||||
|
{ "no-odr", no_argument, &odr, 0 },
|
||||||
|
{ "odr-mode", required_argument, &odr_mode_parsed, 1 },
|
||||||
|
{ "multifile-pointer-size",
|
||||||
|
required_argument, 0, 'p' },
|
||||||
|
{ "multifile-endian",
|
||||||
|
required_argument, 0, 'e' },
|
||||||
|
{ "jobs", required_argument, 0, 'j' },
|
||||||
|
{ NULL, no_argument, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Struct describing various usage aspects of a command line option. */
|
||||||
|
struct option_help
|
||||||
|
{
|
||||||
|
const char *short_name;
|
||||||
|
const char *long_name;
|
||||||
|
const char *argument;
|
||||||
|
const char *default_value;
|
||||||
|
const char *msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Describe common command line options. */
|
||||||
|
static struct option_help dwz_common_options_help[] =
|
||||||
|
{
|
||||||
|
{ "q", "quiet", NULL, NULL,
|
||||||
|
"Silence up the most common messages." },
|
||||||
|
{ "l", "low-mem-die-limit", "<COUNT|none>", "10 million DIEs",
|
||||||
|
"Handle files larger than this limit using a slower and more memory"
|
||||||
|
" usage friendly mode and don't optimize those files in multifile mode." },
|
||||||
|
{ "L", "max-die-limit", "<COUNT|none>", "50 million DIEs",
|
||||||
|
"Don't optimize files larger than this limit." },
|
||||||
|
{ NULL, "odr", NULL, NULL,
|
||||||
|
NULL },
|
||||||
|
{ NULL, "no-odr", NULL, "Disabled",
|
||||||
|
"Enable/disable one definition rule optimization." },
|
||||||
|
{ NULL, "odr-mode", "<basic|link>", "link",
|
||||||
|
"Set aggressiveness level of one definition rule optimization." },
|
||||||
|
{ NULL, "import-optimize", NULL, NULL,
|
||||||
|
NULL },
|
||||||
|
{ NULL, "no-import-optimize", NULL, "Enabled",
|
||||||
|
"Enable/disable optimization that reduces the number of"
|
||||||
|
" DW_TAG_imported_unit DIEs." }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Describe single-file command line options. */
|
||||||
|
static struct option_help dwz_single_file_options_help[] =
|
||||||
|
{
|
||||||
|
{ "o", "output", "OUTFILE", NULL,
|
||||||
|
"Place the output in OUTFILE." }
|
||||||
|
};
|
||||||
|
|
||||||
|
#if NATIVE_ENDIAN_VAL == ELFDATA2MSB
|
||||||
|
#define NATIVE_ENDIAN "big"
|
||||||
|
#elif NATIVE_ENDIAN_VAL == ELFDATA2LSB
|
||||||
|
#define NATIVE_ENDIAN "little"
|
||||||
|
#else
|
||||||
|
#define NATIVE_ENDIAN "not available"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Describe mult-file command line options. */
|
||||||
|
static struct option_help dwz_multi_file_options_help[] =
|
||||||
|
{
|
||||||
|
{ "h", "hardlink", NULL, NULL,
|
||||||
|
"Handle hardlinked files as one file." },
|
||||||
|
{ "m", "multifile", "COMMONFILE", NULL,
|
||||||
|
"Enable multifile optimization, placing common DIEs in multifile"
|
||||||
|
" COMMONFILE." },
|
||||||
|
{ "M", "multifile-name", "NAME", NULL,
|
||||||
|
"Set .gnu_debugaltlink or .debug_sup in files to NAME." },
|
||||||
|
{ "r", "relative", NULL, NULL,
|
||||||
|
"Set .gnu_debugaltlink in files to relative path from file directory"
|
||||||
|
" to multifile." },
|
||||||
|
{ "5", "dwarf-5", NULL, NULL,
|
||||||
|
"Emit DWARF 5 standardized supplementary object files instead of"
|
||||||
|
" GNU extension .debug_altlink." },
|
||||||
|
{ "p", "multifile-pointer-size", "<SIZE|auto|native>", "auto",
|
||||||
|
"Set pointer size of multifile, in number of bytes."
|
||||||
|
" Native pointer size is " XSTR (NATIVE_POINTER_SIZE) "." },
|
||||||
|
{ "e", "multifile-endian", "<l|b|auto|native>", "auto",
|
||||||
|
"Set endianity of multifile."
|
||||||
|
" Native endianity is " NATIVE_ENDIAN "." },
|
||||||
|
{ "j", "jobs", "<n>", "number of processors / 2",
|
||||||
|
"Process <n> files in parallel." }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Describe misc command line options. */
|
||||||
|
static struct option_help dwz_misc_options_help[] =
|
||||||
|
{
|
||||||
|
{ "v", "version", NULL, NULL,
|
||||||
|
"Display dwz version information." },
|
||||||
|
{ "?", "help", NULL, NULL,
|
||||||
|
"Display this information." }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Print LEN spaces to STREAM. */
|
||||||
|
static void
|
||||||
|
do_indent (FILE *stream, unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
fprintf (stream, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print MSG to STREAM, indenting to INDENT and wrapping at LIMIT.
|
||||||
|
Assume starting position is at INDENT. */
|
||||||
|
static void
|
||||||
|
wrap (FILE *stream, unsigned int indent, unsigned int limit, const char *msg)
|
||||||
|
{
|
||||||
|
unsigned int len = indent;
|
||||||
|
const char *s = msg;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const char *e = strchr (s, ' ');
|
||||||
|
unsigned int word_len;
|
||||||
|
if (e == NULL)
|
||||||
|
word_len = strlen (s);
|
||||||
|
else
|
||||||
|
word_len = e - s;
|
||||||
|
if (word_len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (len + 1 /* space */ + word_len > limit)
|
||||||
|
{
|
||||||
|
fprintf (stream, "\n");
|
||||||
|
do_indent (stream ,indent);
|
||||||
|
len = indent;
|
||||||
|
}
|
||||||
|
else if (len > indent)
|
||||||
|
{
|
||||||
|
fprintf (stream, " ");
|
||||||
|
len += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e != NULL)
|
||||||
|
{
|
||||||
|
const char *i;
|
||||||
|
for (i = s; i < e; ++i)
|
||||||
|
fprintf (stream, "%c", *i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf (stream, "%s", s);
|
||||||
|
len += word_len;
|
||||||
|
|
||||||
|
if (e == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
s = e + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print OPTIONS_HELP of length H to STREAM, indenting to help message to
|
||||||
|
INDENT an wrapping at LIMIT. */
|
||||||
|
static void
|
||||||
|
print_options_help (FILE *stream, struct option_help *options_help, unsigned int n,
|
||||||
|
unsigned int indent, unsigned int limit)
|
||||||
|
{
|
||||||
|
unsigned len;
|
||||||
|
const char *s;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
fprintf (stream, " ");
|
||||||
|
len += 2;
|
||||||
|
|
||||||
|
s = options_help[i].short_name;
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
fprintf (stream, "-%s", s);
|
||||||
|
len += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = options_help[i].long_name;
|
||||||
|
if (len == 4)
|
||||||
|
{
|
||||||
|
fprintf (stream, ", ");
|
||||||
|
len += 2;
|
||||||
|
}
|
||||||
|
fprintf (stream, "--%s", s);
|
||||||
|
len += 2 + strlen (s);
|
||||||
|
|
||||||
|
s = options_help[i].argument;
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
fprintf (stream, " %s", s);
|
||||||
|
len += 1 + strlen (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
s = options_help[i].msg;
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
assert (IMPLIES (strlen (s) > 0, s[strlen (s) - 1] == '.'));
|
||||||
|
if (len > indent)
|
||||||
|
{
|
||||||
|
fprintf (stream, "\n");
|
||||||
|
do_indent (stream, indent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
do_indent (stream, indent - len);
|
||||||
|
len = indent;
|
||||||
|
|
||||||
|
wrap (stream, indent, limit, s);
|
||||||
|
}
|
||||||
|
fprintf (stream, "\n");
|
||||||
|
|
||||||
|
s = options_help[i].default_value;
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
do_indent (stream, indent);
|
||||||
|
fprintf (stream, "Default value: %s.\n", s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print usage and exit. */
|
||||||
|
static void
|
||||||
|
usage (int failing)
|
||||||
|
{
|
||||||
|
unsigned int n, i;
|
||||||
|
unsigned int indent, limit;
|
||||||
|
FILE *stream = failing ? stderr : stdout;
|
||||||
|
const char *header_lines[] = {
|
||||||
|
"dwz [common options] [-h] [-m COMMONFILE] [-M NAME | -r] [-5]",
|
||||||
|
" [-p <SIZE|auto|native>] [-e <l|b|auto|native>] [-j N] [FILES]",
|
||||||
|
"dwz [common options] -o OUTFILE FILE",
|
||||||
|
"dwz [ -v | -? ]"
|
||||||
|
};
|
||||||
|
unsigned int nr_header_lines
|
||||||
|
= sizeof (header_lines) / sizeof (*header_lines);
|
||||||
|
|
||||||
|
fprintf (stream, "Usage:\n");
|
||||||
|
for (i = 0; i < nr_header_lines; ++i)
|
||||||
|
fprintf (stream, " %s\n", header_lines[i]);
|
||||||
|
|
||||||
|
indent = 30;
|
||||||
|
limit = 80;
|
||||||
|
fprintf (stream, "Common options:\n");
|
||||||
|
n = (sizeof (dwz_common_options_help)
|
||||||
|
/ sizeof (dwz_common_options_help[0]));
|
||||||
|
print_options_help (stream, dwz_common_options_help, n, indent, limit);
|
||||||
|
|
||||||
|
fprintf (stream, "Single-file options:\n");
|
||||||
|
n = (sizeof (dwz_single_file_options_help)
|
||||||
|
/ sizeof (dwz_single_file_options_help[0]));
|
||||||
|
print_options_help (stream, dwz_single_file_options_help, n, indent, limit);
|
||||||
|
|
||||||
|
fprintf (stream, "Multi-file options:\n");
|
||||||
|
n = (sizeof (dwz_multi_file_options_help)
|
||||||
|
/ sizeof (dwz_multi_file_options_help[0]));
|
||||||
|
print_options_help (stream, dwz_multi_file_options_help, n, indent, limit);
|
||||||
|
|
||||||
|
fprintf (stream, "Miscellaneous options:\n");
|
||||||
|
n = (sizeof (dwz_misc_options_help)
|
||||||
|
/ sizeof (dwz_misc_options_help[0]));
|
||||||
|
print_options_help (stream, dwz_misc_options_help, n, indent, limit);
|
||||||
|
|
||||||
|
#if DEVEL
|
||||||
|
fprintf (stream, "Development options:\n");
|
||||||
|
fprintf (stream, "%s",
|
||||||
|
(" --devel-trace\n"
|
||||||
|
" --devel-progress\n"
|
||||||
|
" --devel-progress-mem\n"
|
||||||
|
" --devel-stats\n"
|
||||||
|
" --devel-ignore-size\n"
|
||||||
|
" --devel-ignore-locus\n"
|
||||||
|
" --devel-force\n"
|
||||||
|
" --devel-save-temps\n"
|
||||||
|
" --devel-dump-checksum\n"
|
||||||
|
" --devel-dump-dies\n"
|
||||||
|
" --devel-dump-dups\n"
|
||||||
|
" --devel-dump-pus\n"
|
||||||
|
" --devel-unoptimized-multifile\n"
|
||||||
|
" --devel-verify-dups\n"
|
||||||
|
" --devel-verify-edges\n"
|
||||||
|
" --devel-dump-edges\n"
|
||||||
|
" --devel-partition-dups-opt\n"
|
||||||
|
" --devel-die-count-method\n"
|
||||||
|
" --devel-deduplication-mode={none,intra-cu,inter-cu}\n"
|
||||||
|
" --devel-uni-lang / --devel-no-uni-lang\n"
|
||||||
|
" --devel-gen-cu / --devel-no-gen-cu\n"
|
||||||
|
" --devel-skip-producer <producer>\n"));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
exit (failing);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print version and exit. */
|
||||||
|
static void
|
||||||
|
version (void)
|
||||||
|
{
|
||||||
|
printf ("dwz version " DWZ_VERSION "\n"
|
||||||
|
"Copyright (C) " RH_YEARS " Red Hat, Inc.\n"
|
||||||
|
"Copyright (C) " FSF_YEARS " Free Software Foundation, Inc.\n"
|
||||||
|
"Copyright (C) " SUSE_YEARS " SUSE LLC.\n"
|
||||||
|
"This program is free software; you may redistribute it under the terms of\n"
|
||||||
|
"the GNU General Public License version 3 or (at your option) any later version.\n"
|
||||||
|
"This program has absolutely no warranty.\n");
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char **skip_producers;
|
||||||
|
static size_t skip_producers_size;
|
||||||
|
static size_t nr_skip_producers;
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_skip_producer (const char *producer)
|
||||||
|
{
|
||||||
|
size_t alloc_size;
|
||||||
|
if (skip_producers == NULL)
|
||||||
|
{
|
||||||
|
skip_producers_size = 10;
|
||||||
|
alloc_size = skip_producers_size * sizeof (const char *);
|
||||||
|
skip_producers = malloc (alloc_size);
|
||||||
|
}
|
||||||
|
else if (nr_skip_producers == skip_producers_size)
|
||||||
|
{
|
||||||
|
skip_producers_size += 10;
|
||||||
|
alloc_size = skip_producers_size * sizeof (const char *);
|
||||||
|
skip_producers = realloc (skip_producers, alloc_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_producers[nr_skip_producers] = producer;
|
||||||
|
nr_skip_producers++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
skip_producer (const char *producer)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (producer == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (i = 0; i < nr_skip_producers; ++i)
|
||||||
|
{
|
||||||
|
const char *skip = skip_producers[i];
|
||||||
|
if (strncmp (skip, producer, strlen (skip)) == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse command line arguments in ARGV. */
|
||||||
|
void
|
||||||
|
parse_args (int argc, char *argv[], bool *hardlink, const char **outfile)
|
||||||
|
{
|
||||||
|
unsigned long l;
|
||||||
|
char *end;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int option_index = -1;
|
||||||
|
int c = getopt_long (argc, argv, "m:o:qhl:L:M:r?v5p:e:j:", dwz_options,
|
||||||
|
&option_index);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case '?':
|
||||||
|
usage (option_index == -1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
/* Option handled by getopt_long. */
|
||||||
|
if (die_count_method_parsed)
|
||||||
|
{
|
||||||
|
die_count_method_parsed = 0;
|
||||||
|
if (strcmp (optarg, "none") == 0)
|
||||||
|
{
|
||||||
|
die_count_method = none;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strcmp (optarg, "estimate") == 0)
|
||||||
|
{
|
||||||
|
die_count_method = estimate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
error (1, 0, "invalid argument --devel-die-count-method %s",
|
||||||
|
optarg);
|
||||||
|
}
|
||||||
|
if (deduplication_mode_parsed)
|
||||||
|
{
|
||||||
|
deduplication_mode_parsed = 0;
|
||||||
|
if (strcmp (optarg, "none") == 0)
|
||||||
|
{
|
||||||
|
deduplication_mode = dm_none;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strcmp (optarg, "intra-cu") == 0)
|
||||||
|
{
|
||||||
|
deduplication_mode = dm_intra_cu;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strcmp (optarg, "inter-cu") == 0)
|
||||||
|
{
|
||||||
|
deduplication_mode = dm_inter_cu;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
error (1, 0, "invalid argument --devel-deduplication-mode %s",
|
||||||
|
optarg);
|
||||||
|
}
|
||||||
|
if (odr_mode_parsed)
|
||||||
|
{
|
||||||
|
odr_mode_parsed = 0;
|
||||||
|
if (strcmp (optarg, "basic") == 0)
|
||||||
|
{
|
||||||
|
odr_mode = ODR_BASIC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strcmp (optarg, "link") == 0)
|
||||||
|
{
|
||||||
|
odr_mode = ODR_LINK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
error (1, 0, "invalid argument --odr-mode %s",
|
||||||
|
optarg);
|
||||||
|
}
|
||||||
|
if (skip_producer_parsed)
|
||||||
|
{
|
||||||
|
skip_producer_parsed = 0;
|
||||||
|
add_skip_producer (optarg);
|
||||||
|
|
||||||
|
#if DEVEL
|
||||||
|
skip_producers_p = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'o':
|
||||||
|
*outfile = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
multifile = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'q':
|
||||||
|
quiet = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
*hardlink = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'M':
|
||||||
|
multifile_name = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'r':
|
||||||
|
multifile_relative = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
if (strcmp (optarg, "none") == 0)
|
||||||
|
{
|
||||||
|
low_mem_die_limit = -1U;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
l = strtoul (optarg, &end, 0);
|
||||||
|
if (*end != '\0' || optarg == end || (unsigned int) l != l)
|
||||||
|
error (1, 0, "invalid argument -l %s", optarg);
|
||||||
|
low_mem_die_limit = l;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'L':
|
||||||
|
if (strcmp (optarg, "none") == 0)
|
||||||
|
{
|
||||||
|
max_die_limit = -1U;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
l = strtoul (optarg, &end, 0);
|
||||||
|
if (*end != '\0' || optarg == end || (unsigned int) l != l)
|
||||||
|
error (1, 0, "invalid argument -L %s", optarg);
|
||||||
|
max_die_limit = l;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '5':
|
||||||
|
dwarf_5 = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
if (strcmp (optarg, "auto") == 0)
|
||||||
|
{
|
||||||
|
multifile_force_ptr_size = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strcmp (optarg, "native") == 0)
|
||||||
|
{
|
||||||
|
multifile_force_ptr_size = NATIVE_POINTER_SIZE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
l = strtoul (optarg, &end, 0);
|
||||||
|
if (*end != '\0' || optarg == end || (unsigned int) l != l)
|
||||||
|
error (1, 0, "invalid argument -l %s", optarg);
|
||||||
|
multifile_force_ptr_size = l;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'e':
|
||||||
|
if (strcmp (optarg, "auto") == 0)
|
||||||
|
{
|
||||||
|
multifile_force_endian = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strcmp (optarg, "native") == 0)
|
||||||
|
{
|
||||||
|
switch (NATIVE_ENDIAN_VAL)
|
||||||
|
{
|
||||||
|
case ELFDATA2MSB:
|
||||||
|
case ELFDATA2LSB:
|
||||||
|
multifile_force_endian = NATIVE_ENDIAN_VAL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error (1, 0, "Cannot determine native endian");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strlen (optarg) != 1)
|
||||||
|
error (1, 0, "invalid argument -l %s", optarg);
|
||||||
|
switch (optarg[0])
|
||||||
|
{
|
||||||
|
case 'l':
|
||||||
|
case 'L':
|
||||||
|
multifile_force_endian = ELFDATA2LSB;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
multifile_force_endian = ELFDATA2MSB;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error (1, 0, "invalid argument -l %s", optarg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'v':
|
||||||
|
version ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'j':
|
||||||
|
l = strtoul (optarg, &end, 0);
|
||||||
|
if (*end != '\0' || optarg == end || (unsigned int) l != l)
|
||||||
|
error (1, 0, "invalid argument -j %s", optarg);
|
||||||
|
max_forks = l;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (progress_mem_p)
|
||||||
|
progress_p = 1;
|
||||||
|
|
||||||
|
/* Specifying a low-mem die-limit that is larger than or equal to the
|
||||||
|
max die-limit has the effect of disabling low-mem mode. Make this
|
||||||
|
explicit by setting it to the 'none' value. */
|
||||||
|
if (low_mem_die_limit != -1U
|
||||||
|
&& low_mem_die_limit >= max_die_limit)
|
||||||
|
low_mem_die_limit = -1U;
|
||||||
|
|
||||||
|
if (multifile_relative && multifile_name)
|
||||||
|
error (1, 0, "-M and -r options can't be specified together");
|
||||||
|
|
||||||
|
if (max_forks == -1)
|
||||||
|
{
|
||||||
|
long nprocs = get_nprocs ();
|
||||||
|
/* Be conservative on max forks: 4 procs may be actually be 4 SMT
|
||||||
|
threads with only 2 cores. */
|
||||||
|
max_forks = nprocs / 2;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
/* Copyright (C) 2001-2021 Red Hat, Inc.
|
||||||
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
Copyright (C) 2019-2021 SUSE LLC.
|
||||||
|
Written by Jakub Jelinek <jakub@redhat.com>, 2012.
|
||||||
|
|
||||||
|
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 2, 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; see the file COPYING. If not, write to
|
||||||
|
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#if DEVEL
|
||||||
|
extern int tracing;
|
||||||
|
extern int ignore_size;
|
||||||
|
extern int ignore_locus;
|
||||||
|
extern int dump_checksum_p;
|
||||||
|
extern int dump_dies_p;
|
||||||
|
extern int dump_dups_p;
|
||||||
|
extern int dump_pus_p;
|
||||||
|
extern int verify_dups_p;
|
||||||
|
extern int verify_edge_freelist;
|
||||||
|
extern int stats_p;
|
||||||
|
extern int checksum_cycle_opt;
|
||||||
|
extern int skip_producers_p;
|
||||||
|
#else
|
||||||
|
#define tracing 0
|
||||||
|
#define ignore_size 0
|
||||||
|
#define ignore_locus 0
|
||||||
|
#define dump_checksum_p 0
|
||||||
|
#define dump_dies_p 0
|
||||||
|
#define dump_dups_p 0
|
||||||
|
#define dump_pus_p 0
|
||||||
|
#define verify_dups_p 0
|
||||||
|
#define stats_p 0
|
||||||
|
#define checksum_cycle_opt 1
|
||||||
|
#define skip_producers_p 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int unoptimized_multifile;
|
||||||
|
extern int save_temps;
|
||||||
|
extern int verify_edges_p;
|
||||||
|
extern int dump_edges_p;
|
||||||
|
extern int partition_dups_opt;
|
||||||
|
extern int progress_p;
|
||||||
|
extern int progress_mem_p;
|
||||||
|
extern int import_opt_p;
|
||||||
|
extern int force_p;
|
||||||
|
extern int max_forks;
|
||||||
|
|
||||||
|
enum deduplication_mode
|
||||||
|
{
|
||||||
|
dm_none,
|
||||||
|
dm_intra_cu,
|
||||||
|
dm_inter_cu
|
||||||
|
};
|
||||||
|
extern enum deduplication_mode deduplication_mode;
|
||||||
|
|
||||||
|
extern int uni_lang_p;
|
||||||
|
extern int gen_cu_p;
|
||||||
|
|
||||||
|
enum die_count_methods
|
||||||
|
{
|
||||||
|
none,
|
||||||
|
estimate
|
||||||
|
};
|
||||||
|
extern enum die_count_methods die_count_method;
|
||||||
|
|
||||||
|
extern int odr;
|
||||||
|
enum odr_mode { ODR_BASIC, ODR_LINK };
|
||||||
|
extern enum odr_mode odr_mode;
|
||||||
|
|
||||||
|
extern const char *multifile;
|
||||||
|
extern const char *multifile_name;
|
||||||
|
extern bool multifile_relative;
|
||||||
|
extern int multifile_force_ptr_size;
|
||||||
|
extern int multifile_force_endian;
|
||||||
|
|
||||||
|
extern unsigned char multifile_mode;
|
||||||
|
|
||||||
|
extern bool dwarf_5;
|
||||||
|
|
||||||
|
extern bool quiet;
|
||||||
|
|
||||||
|
extern unsigned int low_mem_die_limit;
|
||||||
|
extern unsigned int max_die_limit;
|
||||||
|
|
||||||
|
extern void parse_args (int, char *[], bool *, const char **);
|
||||||
|
extern bool skip_producer (const char *producer);
|
|
@ -3,7 +3,7 @@
|
||||||
f="$1"
|
f="$1"
|
||||||
|
|
||||||
size=$(readelf -WS "$f" \
|
size=$(readelf -WS "$f" \
|
||||||
| egrep "[ \t]\.debug_info" \
|
| grep -E "[ \t]\.debug_info" \
|
||||||
| sed 's/.*\.debug_info//' \
|
| sed 's/.*\.debug_info//' \
|
||||||
| awk '{print $4}')
|
| awk '{print $4}')
|
||||||
size=$((16#$size))
|
size=$((16#$size))
|
||||||
|
|
|
@ -52,10 +52,16 @@ echo Bumped version: major: $major, minor: $minor
|
||||||
|
|
||||||
version=$major.$minor
|
version=$major.$minor
|
||||||
|
|
||||||
|
set +x
|
||||||
|
|
||||||
echo $version > VERSION
|
echo $version > VERSION
|
||||||
|
|
||||||
git add VERSION
|
git add VERSION
|
||||||
|
|
||||||
git commit -m "Bump version to $version"
|
git commit -m "Bump version to $version"
|
||||||
|
|
||||||
git tag dwz-$version
|
git push origin master:master
|
||||||
|
|
||||||
|
git tag -s -m "dwz $version release" dwz-$version
|
||||||
|
|
||||||
|
git push origin dwz-$version
|
||||||
|
|
|
@ -128,6 +128,8 @@ main ()
|
||||||
tmp=$(mktemp)
|
tmp=$(mktemp)
|
||||||
|
|
||||||
for f in *.c *.h *.def; do
|
for f in *.c *.h *.def; do
|
||||||
|
if test "$f" = "native.c"; then continue; fi
|
||||||
|
|
||||||
if ! grep -q "Copyright (C)" $f; then
|
if ! grep -q "Copyright (C)" $f; then
|
||||||
echo "error: found file without copyright marker: $f"
|
echo "error: found file without copyright marker: $f"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
@ -4,7 +4,7 @@ set -e
|
||||||
|
|
||||||
pwd=$(pwd -P)
|
pwd=$(pwd -P)
|
||||||
|
|
||||||
version="$1"
|
version=$(cat VERSION)
|
||||||
|
|
||||||
tag=dwz-$version
|
tag=dwz-$version
|
||||||
rootdir=dwz
|
rootdir=dwz
|
||||||
|
|
14
dwz.1
14
dwz.1
|
@ -77,6 +77,16 @@ the executable or shared library to the file named in the argument
|
||||||
of the \fB-m\fR option. Either \fB-M\fR or \fB-r\fR
|
of the \fB-m\fR option. Either \fB-M\fR or \fB-r\fR
|
||||||
option can be specified, but not both.
|
option can be specified, but not both.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-p N \-\-multifile-pointer-size <N|auto|native>
|
||||||
|
Specify the pointer size of the multifile, in bytes. If auto, use the
|
||||||
|
pointer size of the files, provided they match. If native, use native pointer
|
||||||
|
size, as specified in the help message.
|
||||||
|
.TP
|
||||||
|
.B \-p <l|b|auto> \-\-multifile-endian <l|b|auto|native>
|
||||||
|
Specify the endianity of the multifile. If auto, use the endianity of
|
||||||
|
the files, provided they match. If native, use native endianity, as specified
|
||||||
|
in the help message.
|
||||||
|
.TP
|
||||||
.B \-q \-\-quiet
|
.B \-q \-\-quiet
|
||||||
Silence up some of the most common messages.
|
Silence up some of the most common messages.
|
||||||
.TP
|
.TP
|
||||||
|
@ -111,6 +121,10 @@ Emit standard DWARF 5 Supplementary Object Files with \fI.debug_sup\fR and
|
||||||
corresponding forms, instead of the GNU extension \fI.gnu_debugaltlink\fR
|
corresponding forms, instead of the GNU extension \fI.gnu_debugaltlink\fR
|
||||||
and corresponding forms.
|
and corresponding forms.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-j <N> \-\-jobs <N>
|
||||||
|
Process \fIN\fR files in parallel. The default is processors / 2. Disabled
|
||||||
|
when multifile is used.
|
||||||
|
.TP
|
||||||
.B \-\-odr / \-\-no-odr
|
.B \-\-odr / \-\-no-odr
|
||||||
.B Experimental.
|
.B Experimental.
|
||||||
Enable/disable One-Definition-Rule optimization for C++ compilation units.
|
Enable/disable One-Definition-Rule optimization for C++ compilation units.
|
||||||
|
|
139
hashtab.c
139
hashtab.c
|
@ -626,142 +626,3 @@ htab_restore (htab, name, restorefn)
|
||||||
fclose (f);
|
fclose (f);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* DERIVED FROM:
|
|
||||||
--------------------------------------------------------------------
|
|
||||||
lookup2.c, by Bob Jenkins, December 1996, Public Domain.
|
|
||||||
hash(), hash2(), hash3, and mix() are externally useful functions.
|
|
||||||
Routines to test the hash are included if SELF_TEST is defined.
|
|
||||||
You can use this free for any purpose. It has no warranty.
|
|
||||||
--------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
--------------------------------------------------------------------
|
|
||||||
mix -- mix 3 32-bit values reversibly.
|
|
||||||
For every delta with one or two bit set, and the deltas of all three
|
|
||||||
high bits or all three low bits, whether the original value of a,b,c
|
|
||||||
is almost all zero or is uniformly distributed,
|
|
||||||
* If mix() is run forward or backward, at least 32 bits in a,b,c
|
|
||||||
have at least 1/4 probability of changing.
|
|
||||||
* If mix() is run forward, every bit of c will change between 1/3 and
|
|
||||||
2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
|
|
||||||
mix() was built out of 36 single-cycle latency instructions in a
|
|
||||||
structure that could supported 2x parallelism, like so:
|
|
||||||
a -= b;
|
|
||||||
a -= c; x = (c>>13);
|
|
||||||
b -= c; a ^= x;
|
|
||||||
b -= a; x = (a<<8);
|
|
||||||
c -= a; b ^= x;
|
|
||||||
c -= b; x = (b>>13);
|
|
||||||
...
|
|
||||||
Unfortunately, superscalar Pentiums and Sparcs can't take advantage
|
|
||||||
of that parallelism. They've also turned some of those single-cycle
|
|
||||||
latency instructions into multi-cycle latency instructions. Still,
|
|
||||||
this is the fastest good hash I could find. There were about 2^^68
|
|
||||||
to choose from. I only looked at a billion or so.
|
|
||||||
--------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
/* same, but slower, works on systems that might have 8 byte hashval_t's */
|
|
||||||
#define mix(a,b,c) \
|
|
||||||
{ \
|
|
||||||
a -= b; a -= c; a ^= (c>>13); \
|
|
||||||
b -= c; b -= a; b ^= (a<< 8); \
|
|
||||||
c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \
|
|
||||||
a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \
|
|
||||||
b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
|
|
||||||
c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
|
|
||||||
a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
|
|
||||||
b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
|
|
||||||
c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
--------------------------------------------------------------------
|
|
||||||
hash() -- hash a variable-length key into a 32-bit value
|
|
||||||
k : the key (the unaligned variable-length array of bytes)
|
|
||||||
len : the length of the key, counting by bytes
|
|
||||||
level : can be any 4-byte value
|
|
||||||
Returns a 32-bit value. Every bit of the key affects every bit of
|
|
||||||
the return value. Every 1-bit and 2-bit delta achieves avalanche.
|
|
||||||
About 36+6len instructions.
|
|
||||||
|
|
||||||
The best hash table sizes are powers of 2. There is no need to do
|
|
||||||
mod a prime (mod is sooo slow!). If you need less than 32 bits,
|
|
||||||
use a bitmask. For example, if you need only 10 bits, do
|
|
||||||
h = (h & hashmask(10));
|
|
||||||
In which case, the hash table should have hashsize(10) elements.
|
|
||||||
|
|
||||||
If you are hashing n strings (ub1 **)k, do it like this:
|
|
||||||
for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
|
|
||||||
|
|
||||||
By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
|
|
||||||
code any way you wish, private, educational, or commercial. It's free.
|
|
||||||
|
|
||||||
See http://burtleburtle.net/bob/hash/evahash.html
|
|
||||||
Use for hash table lookup, or anything where one collision in 2^32 is
|
|
||||||
acceptable. Do NOT use for cryptographic purposes.
|
|
||||||
--------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
hashval_t
|
|
||||||
iterative_hash (const void *k_in /* the key */,
|
|
||||||
register size_t length /* the length of the key */,
|
|
||||||
register hashval_t initval /* the previous hash, or
|
|
||||||
an arbitrary value */)
|
|
||||||
{
|
|
||||||
register const unsigned char *k = (const unsigned char *)k_in;
|
|
||||||
register hashval_t a,b,c,len;
|
|
||||||
|
|
||||||
/* Set up the internal state */
|
|
||||||
len = length;
|
|
||||||
a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
|
|
||||||
c = initval; /* the previous hash value */
|
|
||||||
|
|
||||||
/*---------------------------------------- handle most of the key */
|
|
||||||
#ifndef WORDS_BIGENDIAN
|
|
||||||
/* On a little-endian machine, if the data is 4-byte aligned we can hash
|
|
||||||
by word for better speed. This gives nondeterministic results on
|
|
||||||
big-endian machines. */
|
|
||||||
if (sizeof (hashval_t) == 4 && (((size_t)k)&3) == 0)
|
|
||||||
while (len >= 12) /* aligned */
|
|
||||||
{
|
|
||||||
a += *(hashval_t *)(k+0);
|
|
||||||
b += *(hashval_t *)(k+4);
|
|
||||||
c += *(hashval_t *)(k+8);
|
|
||||||
mix(a,b,c);
|
|
||||||
k += 12; len -= 12;
|
|
||||||
}
|
|
||||||
else /* unaligned */
|
|
||||||
#endif
|
|
||||||
while (len >= 12)
|
|
||||||
{
|
|
||||||
a += (k[0] +((hashval_t)k[1]<<8) +((hashval_t)k[2]<<16) +((hashval_t)k[3]<<24));
|
|
||||||
b += (k[4] +((hashval_t)k[5]<<8) +((hashval_t)k[6]<<16) +((hashval_t)k[7]<<24));
|
|
||||||
c += (k[8] +((hashval_t)k[9]<<8) +((hashval_t)k[10]<<16)+((hashval_t)k[11]<<24));
|
|
||||||
mix(a,b,c);
|
|
||||||
k += 12; len -= 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------- handle the last 11 bytes */
|
|
||||||
c += length;
|
|
||||||
switch(len) /* all the case statements fall through */
|
|
||||||
{
|
|
||||||
case 11: c+=((hashval_t)k[10]<<24); /* fall through */
|
|
||||||
case 10: c+=((hashval_t)k[9]<<16); /* fall through */
|
|
||||||
case 9 : c+=((hashval_t)k[8]<<8); /* fall through */
|
|
||||||
/* the first byte of c is reserved for the length */
|
|
||||||
case 8 : b+=((hashval_t)k[7]<<24); /* fall through */
|
|
||||||
case 7 : b+=((hashval_t)k[6]<<16); /* fall through */
|
|
||||||
case 6 : b+=((hashval_t)k[5]<<8); /* fall through */
|
|
||||||
case 5 : b+=k[4]; /* fall through */
|
|
||||||
case 4 : a+=((hashval_t)k[3]<<24); /* fall through */
|
|
||||||
case 3 : a+=((hashval_t)k[2]<<16); /* fall through */
|
|
||||||
case 2 : a+=((hashval_t)k[1]<<8); /* fall through */
|
|
||||||
case 1 : a+=k[0];
|
|
||||||
/* case 0: nothing left to add */
|
|
||||||
}
|
|
||||||
mix(a,b,c);
|
|
||||||
/*-------------------------------------------- report the result */
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
|
@ -153,11 +153,6 @@ extern void htab_restore (htab_t, const char *, htab_restorefn);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* An iterative hash function for arbitrary data. */
|
|
||||||
extern hashval_t iterative_hash (const void *, size_t, hashval_t);
|
|
||||||
/* Shorthand for hashing something with an intrinsic size. */
|
|
||||||
#define iterative_hash_object(OB,INIT) iterative_hash (&OB, sizeof (OB), INIT)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/* Copyright (C) 2001-2021 Red Hat, Inc.
|
||||||
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
Copyright (C) 2019-2021 SUSE LLC.
|
||||||
|
Written by Jakub Jelinek <jakub@redhat.com>, 2012.
|
||||||
|
|
||||||
|
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 2, 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; see the file COPYING. If not, write to
|
||||||
|
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* Big pool allocator. obstack isn't efficient, because it aligns everything
|
||||||
|
too much, and allocates too small chunks. All these objects are only freed
|
||||||
|
together. */
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "pool.h"
|
||||||
|
|
||||||
|
/* Pointer to the start of the current pool chunk, current first free byte
|
||||||
|
in the chunk and byte after the end of the current pool chunk. */
|
||||||
|
|
||||||
|
static unsigned char *pool, *pool_next, *pool_limit;
|
||||||
|
|
||||||
|
extern void dwz_oom (void);
|
||||||
|
|
||||||
|
/* Allocate SIZE bytes with ALIGN bytes alignment from the pool. */
|
||||||
|
void *
|
||||||
|
pool_alloc_1 (unsigned int align, unsigned int size)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
if (pool == NULL
|
||||||
|
|| (size_t) (pool_limit - pool_next) < (size_t) align + size)
|
||||||
|
{
|
||||||
|
size_t new_size = (size_t) align + size;
|
||||||
|
unsigned char *new_pool;
|
||||||
|
new_size += sizeof (void *);
|
||||||
|
if (new_size < 16384 * 1024 - 64)
|
||||||
|
new_size = 16384 * 1024 - 64;
|
||||||
|
new_pool = (unsigned char *) malloc (new_size);
|
||||||
|
if (new_pool == NULL)
|
||||||
|
dwz_oom ();
|
||||||
|
*(unsigned char **) new_pool = pool;
|
||||||
|
pool_next = new_pool + sizeof (unsigned char *);
|
||||||
|
pool_limit = new_pool + new_size;
|
||||||
|
pool = new_pool;
|
||||||
|
}
|
||||||
|
pool_next = (unsigned char *) (((uintptr_t) pool_next + align - 1)
|
||||||
|
& ~(uintptr_t) (align - 1));
|
||||||
|
ret = pool_next;
|
||||||
|
pool_next += size;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finalize a pool and return it. */
|
||||||
|
unsigned char *
|
||||||
|
finalize_pool (void)
|
||||||
|
{
|
||||||
|
unsigned char *ret = pool;
|
||||||
|
pool = NULL;
|
||||||
|
pool_next = NULL;
|
||||||
|
pool_limit = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free pool P. */
|
||||||
|
static void
|
||||||
|
pool_destroy_1 (unsigned char *p)
|
||||||
|
{
|
||||||
|
while (p)
|
||||||
|
{
|
||||||
|
void *elem = (void *) p;
|
||||||
|
p = *(unsigned char **) p;
|
||||||
|
free (elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free pool P, or the current pool if NULL. */
|
||||||
|
void
|
||||||
|
pool_destroy (unsigned char *p)
|
||||||
|
{
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
pool_destroy_1 (p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pool_destroy_1 (pool);
|
||||||
|
pool = NULL;
|
||||||
|
pool_next = NULL;
|
||||||
|
pool_limit = NULL;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* Copyright (C) 2001-2021 Red Hat, Inc.
|
||||||
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
Copyright (C) 2019-2021 SUSE LLC.
|
||||||
|
Written by Jakub Jelinek <jakub@redhat.com>, 2012.
|
||||||
|
|
||||||
|
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 2, 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; see the file COPYING. If not, write to
|
||||||
|
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
extern void *pool_alloc_1 (unsigned int, unsigned int);
|
||||||
|
extern unsigned char *finalize_pool (void);
|
||||||
|
extern void pool_destroy (unsigned char *);
|
||||||
|
|
||||||
|
#define pool_alloc(name, size) \
|
||||||
|
(struct name *) pool_alloc_1 (ALIGNOF_STRUCT (name), size)
|
|
@ -0,0 +1,13 @@
|
||||||
|
struct s;
|
||||||
|
|
||||||
|
struct s {
|
||||||
|
struct s *p;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct s var;
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
readelf_flags=""
|
||||||
|
if readelf -h 2>&1 | grep -q "\-wN"; then
|
||||||
|
readelf_flags=-wN
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp $execs/cycle 1
|
||||||
|
|
||||||
|
# Using mode 3 in checksum_die_ref.
|
||||||
|
$execs/dwz-for-test 1 -o 1.z --devel-dump-dies 2> DUMP.1
|
||||||
|
rm -f 1.z
|
||||||
|
|
||||||
|
# Skipping mode 3 in checksum_die_ref.
|
||||||
|
$execs/dwz-for-test 1 -o 1.z --devel-dump-dies --devel-no-checksum-cycle-opt 2> DUMP.2
|
||||||
|
rm -f 1.z
|
||||||
|
|
||||||
|
# Verify that mode 3 and mode 4 have different checksums.
|
||||||
|
grep " s structure_type" DUMP.1 > LINE.1
|
||||||
|
grep " s structure_type" DUMP.2 > LINE.2
|
||||||
|
! diff -q LINE.1 LINE.2
|
||||||
|
rm -f DUMP.1 DUMP.2 LINE.1 LINE.2
|
||||||
|
|
||||||
|
# Verify that dwz actually works with --devel-no-checksum-cycle-opt.
|
||||||
|
cp 1 2
|
||||||
|
$execs/dwz-for-test -m 3 1 2 --devel-no-checksum-cycle-opt --devel-ignore-size
|
||||||
|
|
||||||
|
cnt=$(readelf -wi 3 | grep -c "DW_AT_name.*: s$")
|
||||||
|
[ $cnt -eq 1 ]
|
||||||
|
|
||||||
|
# Even with -wN readelf 2.38-15.fc37 follows and prints the contents
|
||||||
|
# of the alt file. So make sure it cannot do that by removing it.
|
||||||
|
rm 3
|
||||||
|
|
||||||
|
cnt=$(readelf -wi $readelf_flags 1 | grep -c "DW_AT_name.*: s$" || true)
|
||||||
|
[ $cnt -eq 0 ]
|
||||||
|
|
||||||
|
rm -f 1 2 3
|
|
@ -6,7 +6,7 @@ cnt=$(readelf -wi 1 \
|
||||||
|
|
||||||
[ $cnt -eq 2 ]
|
[ $cnt -eq 2 ]
|
||||||
|
|
||||||
$execs/dwz-for-test 1 2>/dev/null
|
$execs/dwz-for-test 1 2>/dev/null
|
||||||
|
|
||||||
cnt=$(readelf -wi 1 \
|
cnt=$(readelf -wi 1 \
|
||||||
| grep 'DW_AT_name.*: aaa' \
|
| grep 'DW_AT_name.*: aaa' \
|
||||||
|
@ -16,7 +16,7 @@ cnt=$(readelf -wi 1 \
|
||||||
|
|
||||||
cp $execs/two-typedef 1
|
cp $execs/two-typedef 1
|
||||||
|
|
||||||
$execs/dwz-for-test --devel-ignore-locus --devel-ignore-size 1
|
$execs/dwz-for-test --devel-ignore-locus --devel-ignore-size 1
|
||||||
|
|
||||||
cnt=$(readelf -wi 1 \
|
cnt=$(readelf -wi 1 \
|
||||||
| grep 'DW_AT_name.*: aaa' \
|
| grep 'DW_AT_name.*: aaa' \
|
||||||
|
|
|
@ -6,7 +6,7 @@ cnt=$(readelf -wi 1 \
|
||||||
|
|
||||||
[ $cnt -eq 0 ]
|
[ $cnt -eq 0 ]
|
||||||
|
|
||||||
$execs/dwz-for-test 1 2>/dev/null
|
$execs/dwz-for-test 1 2>/dev/null
|
||||||
|
|
||||||
cnt=$(readelf -wi 1 \
|
cnt=$(readelf -wi 1 \
|
||||||
| grep '(DW_TAG_partial_unit' \
|
| grep '(DW_TAG_partial_unit' \
|
||||||
|
@ -18,7 +18,7 @@ fi
|
||||||
|
|
||||||
cp $execs/min 1
|
cp $execs/min 1
|
||||||
|
|
||||||
$execs/dwz-for-test --devel-ignore-size 1
|
$execs/dwz-for-test --devel-ignore-size 1
|
||||||
|
|
||||||
cnt=$(readelf -wi 1 \
|
cnt=$(readelf -wi 1 \
|
||||||
| grep '(DW_TAG_partial_unit' \
|
| grep '(DW_TAG_partial_unit' \
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
cp $execs/hello 1
|
cp $execs/hello 1
|
||||||
|
|
||||||
$execs/dwz-for-test --devel-trace 1 2>/dev/null
|
$execs/dwz-for-test --devel-trace 1 2>/dev/null
|
||||||
|
|
||||||
rm -f 1
|
rm -f 1
|
||||||
|
|
|
@ -400,3 +400,4 @@ loclist:
|
||||||
.byte 1
|
.byte 1
|
||||||
|
|
||||||
.Lline1_end:
|
.Lline1_end:
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
cp $execs/hello 1
|
cp $execs/hello 1
|
||||||
|
|
||||||
gdb-add-index 1
|
# Redirect gdb-add-index stderr to stdout.
|
||||||
|
# https://sourceware.org/bugzilla/show_bug.cgi?id=29316
|
||||||
|
gdb-add-index 1 2>&1
|
||||||
|
|
||||||
readelf -S 1 | grep -q '\.gdb_index'
|
readelf -S 1 | grep -q '\.gdb_index'
|
||||||
|
|
||||||
|
|
|
@ -154,3 +154,4 @@
|
||||||
.byte 0x0 /* Terminator */
|
.byte 0x0 /* Terminator */
|
||||||
.byte 0x0 /* Terminator */
|
.byte 0x0 /* Terminator */
|
||||||
.byte 0x0 /* Terminator */
|
.byte 0x0 /* Terminator */
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
|
|
|
@ -2,6 +2,11 @@ if ! $execs/dwz-for-test --odr -v 2>/dev/null; then
|
||||||
exit 77
|
exit 77
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
readelf_flags=""
|
||||||
|
if readelf -h 2>&1 | grep -q "\-wN"; then
|
||||||
|
readelf_flags=-wN
|
||||||
|
fi
|
||||||
|
|
||||||
cp $execs/odr-struct 1
|
cp $execs/odr-struct 1
|
||||||
cp 1 2
|
cp 1 2
|
||||||
|
|
||||||
|
@ -39,14 +44,17 @@ for name in member_one member_two member_three member_four; do
|
||||||
[ $cnt -eq 1 ]
|
[ $cnt -eq 1 ]
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Even with -wN readelf 2.38-15.fc37 follows and prints the contents
|
||||||
|
# of the alt file. So make sure it cannot do that by removing it.
|
||||||
|
rm 3
|
||||||
|
|
||||||
for name in aaa bbb ccc; do
|
for name in aaa bbb ccc; do
|
||||||
cnt=$(readelf -wi 1 | grep -c "DW_AT_name.*:.*$name" || true)
|
cnt=$(readelf -wi $readelf_flags 1 | grep -c "DW_AT_name.*:.*$name" || true)
|
||||||
[ $cnt -eq 0 ]
|
[ $cnt -eq 0 ]
|
||||||
done
|
done
|
||||||
|
|
||||||
for name in member_one member_two member_three member_four; do
|
for name in member_one member_two member_three member_four; do
|
||||||
cnt=$(readelf -wi 1 | grep -c "DW_AT_name.*:.*$name" || true)
|
cnt=$(readelf -wi $readelf_flags 1 | grep -c "DW_AT_name.*:.*$name" || true)
|
||||||
[ $cnt -eq 0 ]
|
[ $cnt -eq 0 ]
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,10 @@ for name in member_one member_two member_three member_four; do
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
decl_cnt=$(readelf -wi 1 | grep -c "DW_AT_declaration" || true)
|
# Check that bbb and ccc are present as DW_AT_declaration
|
||||||
|
readelf -wi 1 | grep -3 DW_AT_declaration > decls
|
||||||
|
grep bbb decls >/dev/null
|
||||||
|
grep ccc decls >/dev/null
|
||||||
|
|
||||||
$execs/dwz-for-test --odr 1
|
$execs/dwz-for-test --odr 1
|
||||||
|
|
||||||
|
@ -38,8 +41,9 @@ for name in member_one member_two member_three member_four; do
|
||||||
done
|
done
|
||||||
|
|
||||||
# We expect two decls to be removed, for bbb and ccc.
|
# We expect two decls to be removed, for bbb and ccc.
|
||||||
expected_decl_cnt=$(($decl_cnt - 2))
|
readelf -wi 1 | grep -3 DW_AT_declaration > decls || true
|
||||||
decl_cnt=$(readelf -wi 1 | grep -c "DW_AT_declaration" || true)
|
|
||||||
[ $expected_decl_cnt -eq $decl_cnt ]
|
|
||||||
|
|
||||||
rm -f 1
|
if grep bbb decls >/dev/null ; then exit 1; fi
|
||||||
|
if grep ccc decls >/dev/null ; then exit 2; fi
|
||||||
|
|
||||||
|
rm -f 1 decls
|
||||||
|
|
|
@ -21,7 +21,10 @@ for name in member_one member_two member_three member_four; do
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
decl_cnt=$(readelf -wi 1 | grep -c "DW_AT_declaration" || true)
|
# Check that bbb and ccc are present as DW_AT_declaration
|
||||||
|
readelf -wi 1 | grep -3 DW_AT_declaration > decls
|
||||||
|
grep bbb decls >/dev/null
|
||||||
|
grep ccc decls >/dev/null
|
||||||
|
|
||||||
$execs/dwz-for-test --odr 1
|
$execs/dwz-for-test --odr 1
|
||||||
|
|
||||||
|
@ -38,8 +41,9 @@ for name in member_one member_two member_three member_four; do
|
||||||
done
|
done
|
||||||
|
|
||||||
# We expect two decls to be removed, for bbb and ccc.
|
# We expect two decls to be removed, for bbb and ccc.
|
||||||
expected_decl_cnt=$(($decl_cnt - 2))
|
readelf -wi 1 | grep -3 DW_AT_declaration > decls || true
|
||||||
decl_cnt=$(readelf -wi 1 | grep -c "DW_AT_declaration" || true)
|
|
||||||
[ $expected_decl_cnt -eq $decl_cnt ]
|
|
||||||
|
|
||||||
rm -f 1
|
if grep bbb decls >/dev/null ; then exit 1; fi
|
||||||
|
if grep ccc decls >/dev/null ; then exit 2; fi
|
||||||
|
|
||||||
|
rm -f 1 decls
|
||||||
|
|
|
@ -4,6 +4,4 @@ cp $exec 1
|
||||||
|
|
||||||
dwz 1
|
dwz 1
|
||||||
|
|
||||||
smaller-than.sh 1 $exec
|
|
||||||
|
|
||||||
rm -f 1
|
rm -f 1
|
||||||
|
|
|
@ -24,7 +24,10 @@ if [ $(grep -qv "DWARF compression not beneficial" dwz.err \
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[ $status -eq 0 ]
|
if [ $status -ne 0 ]; then
|
||||||
|
cat dwz.err
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
smaller-than.sh 1 1.saved
|
smaller-than.sh 1 1.saved
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,10 @@ $execs/dwz-for-test \
|
||||||
-l0 \
|
-l0 \
|
||||||
--devel-trace \
|
--devel-trace \
|
||||||
1 2 \
|
1 2 \
|
||||||
|
-j 1 \
|
||||||
2> dwz.err
|
2> dwz.err
|
||||||
|
|
||||||
if egrep -q "Compressing (1|2)$" dwz.err; then
|
if grep -Eq "Compressing (1|2)$" dwz.err; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -512,3 +512,4 @@
|
||||||
.byte 0x0 /* Terminator */
|
.byte 0x0 /* Terminator */
|
||||||
.byte 0x0 /* Terminator */
|
.byte 0x0 /* Terminator */
|
||||||
.byte 0x0 /* Terminator */
|
.byte 0x0 /* Terminator */
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
|
|
|
@ -1666,6 +1666,8 @@ namespace eval Dwarf {
|
||||||
|
|
||||||
_write_deferred_output
|
_write_deferred_output
|
||||||
|
|
||||||
|
_section .note.GNU-stack "" progbits
|
||||||
|
|
||||||
catch {close $_output_file}
|
catch {close $_output_file}
|
||||||
set _output_file {}
|
set _output_file {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,45 @@
|
||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
|
|
||||||
f1=$1
|
f1=$1
|
||||||
f2=$2
|
f2=$2
|
||||||
|
|
||||||
s1=$(ls -l $f1 | awk '{print $5}')
|
section_size ()
|
||||||
s2=$(ls -l $f2 | awk '{print $5}')
|
{
|
||||||
|
local f="$1"
|
||||||
|
local section="$2"
|
||||||
|
|
||||||
|
local s
|
||||||
|
s=$(readelf -S -W $f \
|
||||||
|
| grep "\.debug_$section" \
|
||||||
|
| sed 's/.*\.debug_//' \
|
||||||
|
| awk '{print $5}')
|
||||||
|
|
||||||
|
if [ "$s" = "" ]; then
|
||||||
|
echo 0
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Convert hex to decimal.
|
||||||
|
s=$(printf "%d" $((16#$s)))
|
||||||
|
|
||||||
|
echo $s
|
||||||
|
}
|
||||||
|
|
||||||
|
size ()
|
||||||
|
{
|
||||||
|
local f="$1"
|
||||||
|
|
||||||
|
local total=0
|
||||||
|
local section
|
||||||
|
for section in info abbrev str macro types; do
|
||||||
|
total=$(($total + $(section_size $f $section)))
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $total
|
||||||
|
}
|
||||||
|
|
||||||
|
s1=$(size $f1)
|
||||||
|
s2=$(size $f2)
|
||||||
|
|
||||||
if [ $s1 -ge $s2 ]; then
|
if [ $s1 -ge $s2 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/* Copyright (C) 2001-2021 Red Hat, Inc.
|
||||||
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
Copyright (C) 2019-2021 SUSE LLC.
|
||||||
|
Written by Jakub Jelinek <jakub@redhat.com>, 2012.
|
||||||
|
|
||||||
|
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 2, 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; see the file COPYING. If not, write to
|
||||||
|
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* Utility macros. */
|
||||||
|
|
||||||
|
#define IMPLIES(A, B) (!((A) && !(B)))
|
||||||
|
|
||||||
|
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||||
|
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||||
|
|
||||||
|
#define XSTR(s) STR(s)
|
||||||
|
#define STR(s) #s
|
||||||
|
|
||||||
|
#ifndef USE_GNUC
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define USE_GNUC 1
|
||||||
|
#else
|
||||||
|
#define USE_GNUC 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_GNUC && __GNUC__ >= 3
|
||||||
|
# define likely(x) __builtin_expect (!!(x), 1)
|
||||||
|
# define unlikely(x) __builtin_expect (!!(x), 0)
|
||||||
|
#else
|
||||||
|
# define likely(x) (x)
|
||||||
|
# define unlikely(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_GNUC
|
||||||
|
# define FORCE_INLINE __attribute__((always_inline))
|
||||||
|
# define UNUSED __attribute__((unused))
|
||||||
|
# define USED __attribute__((used))
|
||||||
|
#else
|
||||||
|
# define FORCE_INLINE
|
||||||
|
# define UNUSED
|
||||||
|
# define USED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_GNUC
|
||||||
|
# define ALIGN_STRUCT(name)
|
||||||
|
# define ALIGNOF_STRUCT(name) __alignof__ (struct name)
|
||||||
|
#else
|
||||||
|
# define ALIGN_STRUCT(name) struct align_##name { char c; struct name s; };
|
||||||
|
# define ALIGNOF_STRUCT(name) offsetof (struct align_##name, s)
|
||||||
|
#endif
|
Loading…
Reference in New Issue